diff --git a/test/test.cpp b/test/test.cpp
index f089fcd..669879d 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -16,6 +16,8 @@
 #include "../manager.hpp"
 #include "../config.h"
 #include <cassert>
+#include <iostream>
+#include <algorithm>
 
 constexpr auto SERVICE = "phosphor.inventory.test";
 constexpr auto INTERFACE = IFACE;
@@ -30,46 +32,142 @@
     return static_cast<void *>(nullptr);
 }
 
+/** @class SignalQueue
+ *  @brief Store DBus signals in a queue.
+ */
+class SignalQueue
+{
+    public:
+    ~SignalQueue() = default;
+    SignalQueue() = delete;
+    SignalQueue(const SignalQueue &) = delete;
+    SignalQueue(SignalQueue &&) = default;
+    SignalQueue& operator=(const SignalQueue &) = delete;
+    SignalQueue& operator=(SignalQueue &&) = default;
+    explicit SignalQueue(const std::string &match) :
+        _bus(sdbusplus::bus::new_default()),
+        _match(_bus, match.c_str(), &callback, this),
+        _next(nullptr)
+    {
+    }
+
+    auto &&pop(unsigned timeout=1000000)
+    {
+        while(timeout > 0 && !_next)
+        {
+            _bus.process_discard();
+            _bus.wait(50000);
+            timeout -= 50000;
+        }
+        return std::move(_next);
+    }
+
+    private:
+    static int callback(sd_bus_message *m, void *context, sd_bus_error *)
+    {
+        auto *me = static_cast<SignalQueue *>(context);
+        sd_bus_message_ref(m);
+        sdbusplus::message::message msg{m};
+        me->_next = std::move(msg);
+        return 0;
+    }
+
+    sdbusplus::bus::bus _bus;
+    sdbusplus::server::match::match _match;
+    sdbusplus::message::message _next;
+};
+
+template <typename ...T>
+using Object = std::map<
+        std::string,
+        std::map<
+            std::string,
+            sdbusplus::message::variant<T...>>>;
+
+using ObjectPath = std::string;
+
+/**@brief Find a subset of interfaces and properties in an object. */
+template <typename ...T>
+auto hasProperties(const Object<T...> &l, const Object<T...> &r)
+{
+    Object<T...> result;
+    std::set_difference(
+            r.cbegin(),
+            r.cend(),
+            l.cbegin(),
+            l.cend(),
+            std::inserter(result, result.end()));
+    return result.empty();
+}
+
 void runTests(phosphor::inventory::manager::Manager &mgr)
 {
+    const std::string root{ROOT};
     auto b = sdbusplus::bus::new_default();
-
-    // make sure the notify method works
+    auto notify = [&]()
     {
-        auto m = b.new_method_call(SERVICE, ROOT, INTERFACE, "Notify");
-        m.append("/foo");
+        return b.new_method_call(
+                SERVICE,
+                ROOT,
+                INTERFACE,
+                "Notify");
+    };
 
-        using var = sdbusplus::message::variant<std::string>;
-        using inner = std::map<std::string, var>;
-        using outer = std::map<std::string, inner>;
+    Object<std::string> obj{
+        {
+            "xyz.openbmc_project.Example.Iface1",
+            {{"ExampleProperty1", "test1"}}
+        },
+        {
+            "xyz.openbmc_project.Example.Iface2",
+            {{"ExampleProperty2", "test2"}}
+        },
+    };
 
-        inner i = {{"ExampleProperty1", "test"}};
-        outer o = {{"xyz.openbmc_project.Example.Iface1", i}};
+    // Make sure the notify method works.
+    {
+        ObjectPath relPath{"/foo"};
+        ObjectPath path{root + relPath};
 
-        m.append(o);
-        auto reply = b.call(m);
-        auto cleanup = sdbusplus::message::message(reply);
-        assert(sd_bus_message_get_errno(reply) == 0);
+        SignalQueue queue(
+                "path='" + root + "',member='InterfacesAdded'");
+
+        auto m = notify();
+        m.append(relPath);
+        m.append(obj);
+        b.call(m);
+
+        auto sig{queue.pop()};
+        assert(sig);
+        ObjectPath signalPath;
+        Object<std::string> signalObject;
+        sig.read(signalPath);
+        assert(path == signalPath);
+        sig.read(signalObject);
+        assert(hasProperties(signalObject, obj));
+        auto moreSignals{queue.pop()};
+        assert(!moreSignals);
     }
 
     mgr.shutdown();
+    std::cout << "Success!" << std::endl;
 }
 
 int main()
 {
     auto mgr = phosphor::inventory::manager::Manager(
-            sdbusplus::bus::new_system(),
+            sdbusplus::bus::new_default(),
             SERVICE, ROOT, INTERFACE);
 
     pthread_t t;
     {
-        pthread_create(&t, NULL, server_thread, &mgr);
+        pthread_create(&t, nullptr, server_thread, &mgr);
     }
 
     runTests(mgr);
 
     // Wait for server thread to exit.
-    pthread_join(t, NULL);
+    pthread_join(t, nullptr);
 
     return 0;
 }
