face: pass addFace and NetworkMonitor to ProtocolFactory constructor

refs #4021

Change-Id: I842515eb044bb1c655b347e6069e63c55c4e2d54
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 362527f..9ff5fd5 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -42,6 +42,10 @@
   return id;
 }
 
+EthernetFactory::EthernetFactory(const CtorParams& params)
+  : ProtocolFactory(params)
+{
+}
 
 void
 EthernetFactory::processConfig(OptionalConfigSection configSection,
diff --git a/daemon/face/ethernet-factory.hpp b/daemon/face/ethernet-factory.hpp
index 7480728..e4cf7d9 100644
--- a/daemon/face/ethernet-factory.hpp
+++ b/daemon/face/ethernet-factory.hpp
@@ -40,6 +40,9 @@
   static const std::string&
   getId();
 
+  explicit
+  EthernetFactory(const CtorParams& params);
+
   /** \brief process face_system.ether config section
    */
   void
diff --git a/daemon/face/face-system.cpp b/daemon/face/face-system.cpp
index 7877ed0..57b391d 100644
--- a/daemon/face/face-system.cpp
+++ b/daemon/face/face-system.cpp
@@ -33,18 +33,24 @@
 
 NFD_LOG_INIT("FaceSystem");
 
-FaceSystem::FaceSystem(FaceTable& faceTable, const shared_ptr<ndn::net::NetworkMonitor>& netmon)
+FaceSystem::FaceSystem(FaceTable& faceTable, shared_ptr<ndn::net::NetworkMonitor> netmon)
   : m_faceTable(faceTable)
+  , m_netmon(std::move(netmon))
 {
-  BOOST_ASSERT(netmon != nullptr);
-
-  auto addFace = bind(&FaceTable::add, &m_faceTable, _1);
+  auto pfCtorParams = this->makePFCtorParams();
   for (const std::string& id : ProtocolFactory::listRegistered()) {
     NFD_LOG_TRACE("creating factory " << id);
-    m_factories[id] = ProtocolFactory::create(id, netmon, addFace);
+    m_factories[id] = ProtocolFactory::create(id, pfCtorParams);
   }
 }
 
+ProtocolFactoryCtorParams
+FaceSystem::makePFCtorParams()
+{
+  auto addFace = bind(&FaceTable::add, &m_faceTable, _1);
+  return {addFace, m_netmon};
+}
+
 FaceSystem::FaceSystem(FaceTable& faceTable)
   : FaceSystem(faceTable, make_shared<ndn::net::NetworkMonitor>(getGlobalIoService()))
 {
diff --git a/daemon/face/face-system.hpp b/daemon/face/face-system.hpp
index 6557c72..039c1c9 100644
--- a/daemon/face/face-system.hpp
+++ b/daemon/face/face-system.hpp
@@ -41,6 +41,7 @@
 namespace face {
 
 class ProtocolFactory;
+struct ProtocolFactoryCtorParams;
 
 /** \brief entry point of the face system
  *
@@ -50,7 +51,7 @@
 class FaceSystem : noncopyable
 {
 public:
-  FaceSystem(FaceTable& faceTable, const shared_ptr<ndn::net::NetworkMonitor>& netmon);
+  FaceSystem(FaceTable& faceTable, shared_ptr<ndn::net::NetworkMonitor> netmon);
 
   DEPRECATED(
   explicit
@@ -105,6 +106,10 @@
     friend class FaceSystem;
   };
 
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  ProtocolFactoryCtorParams
+  makePFCtorParams();
+
 private:
   void
   processConfig(const ConfigSection& configSection, bool isDryRun,
@@ -123,6 +128,8 @@
   std::map<std::string, ProtocolFactory*> m_factoryByScheme;
 
   FaceTable& m_faceTable;
+
+  shared_ptr<ndn::net::NetworkMonitor> m_netmon;
 };
 
 } // namespace face
diff --git a/daemon/face/protocol-factory.cpp b/daemon/face/protocol-factory.cpp
index 010190d..0a8a150 100644
--- a/daemon/face/protocol-factory.cpp
+++ b/daemon/face/protocol-factory.cpp
@@ -38,8 +38,7 @@
 }
 
 unique_ptr<ProtocolFactory>
-ProtocolFactory::create(const std::string& id, shared_ptr<ndn::net::NetworkMonitor> netmon,
-                        const FaceCreatedCallback& addFace)
+ProtocolFactory::create(const std::string& id, const CtorParams& params)
 {
   Registry& registry = getRegistry();
   auto found = registry.find(id);
@@ -47,10 +46,7 @@
     return nullptr;
   }
 
-  auto factory = found->second();
-  factory->netmon = std::move(netmon);
-  factory->addFace = addFace;
-  return factory;
+  return found->second(params);
 }
 
 std::set<std::string>
@@ -62,5 +58,13 @@
   return factoryIds;
 }
 
+ProtocolFactory::ProtocolFactory(const CtorParams& params)
+  : addFace(params.addFace)
+  , netmon(params.netmon)
+{
+  BOOST_ASSERT(addFace != nullptr);
+  BOOST_ASSERT(netmon != nullptr);
+}
+
 } // namespace face
 } // namespace nfd
diff --git a/daemon/face/protocol-factory.hpp b/daemon/face/protocol-factory.hpp
index 9d6ad3e..524f901 100644
--- a/daemon/face/protocol-factory.hpp
+++ b/daemon/face/protocol-factory.hpp
@@ -36,6 +36,19 @@
 namespace nfd {
 namespace face {
 
+/** \brief Parameters to ProtocolFactory constructor
+ *
+ *  Every ProtocolFactory subclass is expected to have a constructor that accepts CtorParams,
+ *  which in turn passes it to ProtocolFactory base class constructor. Parameters are passed as a
+ *  struct rather than individually, so that a future change in list of parameters does not
+ *  require updates to subclass constructors.
+ */
+struct ProtocolFactoryCtorParams
+{
+  FaceCreatedCallback addFace;
+  shared_ptr<ndn::net::NetworkMonitor> netmon;
+};
+
 /** \brief Provides support for an underlying protocol
  *  \sa FaceSystem
  *
@@ -46,6 +59,8 @@
 class ProtocolFactory : noncopyable
 {
 public: // registry
+  using CtorParams = ProtocolFactoryCtorParams;
+
   /** \brief Register a protocol factory type
    *  \tparam S subclass of ProtocolFactory
    *  \param id factory identifier
@@ -56,15 +71,14 @@
   {
     Registry& registry = getRegistry();
     BOOST_ASSERT(registry.count(id) == 0);
-    registry[id] = &make_unique<PF>;
+    registry[id] = &make_unique<PF, const CtorParams&>;
   }
 
   /** \brief Create a protocol factory instance
    *  \retval nullptr if factory with \p id is not registered
    */
   static unique_ptr<ProtocolFactory>
-  create(const std::string& id, shared_ptr<ndn::net::NetworkMonitor> netmon,
-         const FaceCreatedCallback& addFace);
+  create(const std::string& id, const CtorParams& params);
 
   /** \brief Get registered protocol factory ids
    */
@@ -72,8 +86,7 @@
   listRegistered();
 
 public:
-  /**
-   * \brief Base class for all exceptions thrown by ProtocolFactory subclasses
+  /** \brief Base class for all exceptions thrown by ProtocolFactory subclasses
    */
   class Error : public std::runtime_error
   {
@@ -138,6 +151,9 @@
   getChannels() const = 0;
 
 protected:
+  explicit
+  ProtocolFactory(const CtorParams& params);
+
   template<typename ChannelMap>
   static std::vector<shared_ptr<const Channel>>
   getChannelsFromMap(const ChannelMap& channelMap)
@@ -148,8 +164,8 @@
   }
 
 private: // registry
-  typedef std::function<unique_ptr<ProtocolFactory>()> CreateFunc;
-  typedef std::map<std::string, CreateFunc> Registry; // indexed by factory id
+  using CreateFunc = std::function<unique_ptr<ProtocolFactory>(const CtorParams&)>;
+  using Registry = std::map<std::string, CreateFunc>; // indexed by factory id
 
   static Registry&
   getRegistry();
@@ -157,14 +173,14 @@
 protected:
   std::set<std::string> providedSchemes; ///< FaceUri schemes provided by this ProtocolFactory
 
+  FaceCreatedCallback addFace; ///< callback when a new face is created
+
   /** \brief NetworkMonitor for listing available network interfaces and monitoring their changes
    *
    *  ProtocolFactory subclass should check the NetworkMonitor has sufficient capabilities prior
    *  to usage.
    */
   shared_ptr<ndn::net::NetworkMonitor> netmon;
-
-  FaceCreatedCallback addFace; ///< callback when a new face is created
 };
 
 } // namespace face
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index e2fb3fe..28ac251 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -40,6 +40,11 @@
   return id;
 }
 
+TcpFactory::TcpFactory(const CtorParams& params)
+  : ProtocolFactory(params)
+{
+}
+
 void
 TcpFactory::processConfig(OptionalConfigSection configSection,
                           FaceSystem::ConfigContext& context)
diff --git a/daemon/face/tcp-factory.hpp b/daemon/face/tcp-factory.hpp
index 4576c65..36ee320 100644
--- a/daemon/face/tcp-factory.hpp
+++ b/daemon/face/tcp-factory.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -40,6 +40,9 @@
   static const std::string&
   getId();
 
+  explicit
+  TcpFactory(const CtorParams& params);
+
   /** \brief process face_system.tcp config section
    */
   void
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index cc02bfc..8303aa8 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -51,6 +51,10 @@
   return id;
 }
 
+UdpFactory::UdpFactory(const CtorParams& params)
+  : ProtocolFactory(params)
+{
+}
 
 void
 UdpFactory::processConfig(OptionalConfigSection configSection,
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index 3ebf0a3..2f809ac 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -56,6 +56,9 @@
   static const std::string&
   getId();
 
+  explicit
+  UdpFactory(const CtorParams& params);
+
   /** \brief process face_system.udp config section
    */
   void
diff --git a/daemon/face/unix-stream-factory.cpp b/daemon/face/unix-stream-factory.cpp
index 2d5fe94..0bba3be 100644
--- a/daemon/face/unix-stream-factory.cpp
+++ b/daemon/face/unix-stream-factory.cpp
@@ -40,6 +40,10 @@
   return id;
 }
 
+UnixStreamFactory::UnixStreamFactory(const CtorParams& params)
+  : ProtocolFactory(params)
+{
+}
 
 void
 UnixStreamFactory::processConfig(OptionalConfigSection configSection,
diff --git a/daemon/face/unix-stream-factory.hpp b/daemon/face/unix-stream-factory.hpp
index 3061abd..53baadf 100644
--- a/daemon/face/unix-stream-factory.hpp
+++ b/daemon/face/unix-stream-factory.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -40,6 +40,9 @@
   static const std::string&
   getId();
 
+  explicit
+  UnixStreamFactory(const CtorParams& params);
+
   /** \brief process face_system.unix config section
    */
   void
diff --git a/daemon/face/websocket-factory.cpp b/daemon/face/websocket-factory.cpp
index 2905ae4..21933a4 100644
--- a/daemon/face/websocket-factory.cpp
+++ b/daemon/face/websocket-factory.cpp
@@ -40,6 +40,10 @@
   return id;
 }
 
+WebSocketFactory::WebSocketFactory(const CtorParams& params)
+  : ProtocolFactory(params)
+{
+}
 
 void
 WebSocketFactory::processConfig(OptionalConfigSection configSection,
diff --git a/daemon/face/websocket-factory.hpp b/daemon/face/websocket-factory.hpp
index b7b7b02..0eaa767 100644
--- a/daemon/face/websocket-factory.hpp
+++ b/daemon/face/websocket-factory.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -40,6 +40,9 @@
   static const std::string&
   getId();
 
+  explicit
+  WebSocketFactory(const CtorParams& params);
+
   /** \brief process face_system.websocket config section
    */
   void
diff --git a/tests/daemon/face/ethernet-factory.t.cpp b/tests/daemon/face/ethernet-factory.t.cpp
index 856a942..e48c38f 100644
--- a/tests/daemon/face/ethernet-factory.t.cpp
+++ b/tests/daemon/face/ethernet-factory.t.cpp
@@ -36,15 +36,10 @@
 namespace face {
 namespace tests {
 
-BOOST_AUTO_TEST_SUITE(Face)
-BOOST_FIXTURE_TEST_SUITE(TestEthernetFactory, EthernetFixture)
-
-using face::Face;
-
-class EthernetConfigFixture : public EthernetFixture
-                            , public FaceSystemFixture
+class EthernetFactoryFixture : public EthernetFixture
+                             , public FaceSystemFactoryFixture<EthernetFactory>
 {
-public:
+protected:
   std::vector<const Face*>
   listEtherMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
   {
@@ -58,7 +53,12 @@
   }
 };
 
-BOOST_FIXTURE_TEST_SUITE(ProcessConfig, EthernetConfigFixture)
+BOOST_AUTO_TEST_SUITE(Face)
+BOOST_FIXTURE_TEST_SUITE(TestEthernetFactory, EthernetFactoryFixture)
+
+using nfd::Face;
+
+BOOST_AUTO_TEST_SUITE(ProcessConfig)
 
 BOOST_AUTO_TEST_CASE(Normal)
 {
@@ -313,16 +313,12 @@
 
 BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  EthernetFactory factory;
-
   auto channels = factory.getChannels();
   BOOST_CHECK_EQUAL(channels.empty(), true);
 }
 
 BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
 {
-  EthernetFactory factory;
-
   createFace(factory,
              FaceUri("ether://[00:00:5e:00:53:5e]"),
              {},
diff --git a/tests/daemon/face/face-system-fixture.hpp b/tests/daemon/face/face-system-fixture.hpp
index f1ea72c..b6143d4 100644
--- a/tests/daemon/face/face-system-fixture.hpp
+++ b/tests/daemon/face/face-system-fixture.hpp
@@ -113,6 +113,21 @@
   FaceSystem faceSystem;
 };
 
+/** \brief FaceSystemFixture with a ProtocolFactory reference
+ */
+template<typename FactoryType>
+class FaceSystemFactoryFixture : public FaceSystemFixture
+{
+protected:
+  FaceSystemFactoryFixture()
+    : factory(getFactoryById<FactoryType>(FactoryType::getId()))
+  {
+  }
+
+protected:
+  FactoryType& factory;
+};
+
 } // namespace tests
 } // namespace face
 } // namespace nfd
diff --git a/tests/daemon/face/face-system.t.cpp b/tests/daemon/face/face-system.t.cpp
index 590c063..1e46240 100644
--- a/tests/daemon/face/face-system.t.cpp
+++ b/tests/daemon/face/face-system.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -40,6 +40,11 @@
 class DummyProtocolFactory : public ProtocolFactory
 {
 public:
+  DummyProtocolFactory(const CtorParams& params)
+    : ProtocolFactory(params)
+  {
+  }
+
   void
   processConfig(OptionalConfigSection configSection,
                 FaceSystem::ConfigContext& context) override
@@ -81,8 +86,8 @@
 
 BOOST_AUTO_TEST_CASE(Normal)
 {
-  faceSystem.m_factories["f1"] = make_unique<DummyProtocolFactory>();
-  faceSystem.m_factories["f2"] = make_unique<DummyProtocolFactory>();
+  faceSystem.m_factories["f1"] = make_unique<DummyProtocolFactory>(faceSystem.makePFCtorParams());
+  faceSystem.m_factories["f2"] = make_unique<DummyProtocolFactory>(faceSystem.makePFCtorParams());
   auto f1 = static_cast<DummyProtocolFactory*>(faceSystem.getFactoryById("f1"));
   auto f2 = static_cast<DummyProtocolFactory*>(faceSystem.getFactoryById("f2"));
 
@@ -119,8 +124,8 @@
 
 BOOST_AUTO_TEST_CASE(OmittedSection)
 {
-  faceSystem.m_factories["f1"] = make_unique<DummyProtocolFactory>();
-  faceSystem.m_factories["f2"] = make_unique<DummyProtocolFactory>();
+  faceSystem.m_factories["f1"] = make_unique<DummyProtocolFactory>(faceSystem.makePFCtorParams());
+  faceSystem.m_factories["f2"] = make_unique<DummyProtocolFactory>(faceSystem.makePFCtorParams());
   auto f1 = static_cast<DummyProtocolFactory*>(faceSystem.getFactoryById("f1"));
   auto f2 = static_cast<DummyProtocolFactory*>(faceSystem.getFactoryById("f2"));
 
@@ -165,7 +170,7 @@
 
 BOOST_AUTO_TEST_CASE(ChangeProvidedSchemes)
 {
-  faceSystem.m_factories["f1"] = make_unique<DummyProtocolFactory>();
+  faceSystem.m_factories["f1"] = make_unique<DummyProtocolFactory>(faceSystem.makePFCtorParams());
   auto f1 = static_cast<DummyProtocolFactory*>(faceSystem.getFactoryById("f1"));
 
   const std::string CONFIG = R"CONFIG(
diff --git a/tests/daemon/face/tcp-factory.t.cpp b/tests/daemon/face/tcp-factory.t.cpp
index a66e46a..d994fa2 100644
--- a/tests/daemon/face/tcp-factory.t.cpp
+++ b/tests/daemon/face/tcp-factory.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -33,12 +33,14 @@
 namespace face {
 namespace tests {
 
+using TcpFactoryFixture = FaceSystemFactoryFixture<TcpFactory>;
+
 BOOST_AUTO_TEST_SUITE(Face)
-BOOST_FIXTURE_TEST_SUITE(TestTcpFactory, BaseFixture)
+BOOST_FIXTURE_TEST_SUITE(TestTcpFactory, TcpFactoryFixture)
 
 using nfd::Face;
 
-BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceSystemFixture)
+BOOST_AUTO_TEST_SUITE(ProcessConfig)
 
 BOOST_AUTO_TEST_CASE(Normal)
 {
@@ -58,7 +60,6 @@
   parseConfig(CONFIG, true);
   parseConfig(CONFIG, false);
 
-  auto& factory = this->getFactoryById<TcpFactory>("tcp");
   BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
 }
 
@@ -73,7 +74,6 @@
   parseConfig(CONFIG, true);
   parseConfig(CONFIG, false);
 
-  auto& factory = this->getFactoryById<TcpFactory>("tcp");
   BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
 }
 
@@ -131,8 +131,6 @@
 
 BOOST_AUTO_TEST_CASE(ChannelMap)
 {
-  TcpFactory factory;
-
   shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
   shared_ptr<TcpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
   BOOST_CHECK_EQUAL(channel1, channel1a);
@@ -148,7 +146,6 @@
 
 BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  TcpFactory factory;
   BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
 
   std::vector<shared_ptr<const Channel>> expectedChannels;
@@ -166,8 +163,6 @@
 
 BOOST_AUTO_TEST_CASE(FaceCreate)
 {
-  TcpFactory factory;
-
   createFace(factory,
              FaceUri("tcp4://127.0.0.1:6363"),
              {},
@@ -201,7 +196,6 @@
 
 BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
 {
-  TcpFactory factory;
   factory.createChannel("127.0.0.1", "20071");
 
   createFace(factory,
@@ -237,7 +231,7 @@
               "Local fields can only be enabled on faces with local scope"});
 }
 
-class FaceCreateTimeoutFixture : public BaseFixture
+class FaceCreateTimeoutFixture : public TcpFactoryFixture
 {
 public:
   void
@@ -264,7 +258,6 @@
 
 BOOST_FIXTURE_TEST_CASE(FaceCreateTimeout, FaceCreateTimeoutFixture)
 {
-  TcpFactory factory;
   factory.createChannel("0.0.0.0", "20070");
 
   factory.createFace(FaceUri("tcp4://192.0.2.1:20070"),
@@ -278,7 +271,7 @@
   BOOST_CHECK(face == nullptr);
 }
 
-class FakeNetworkInterfaceFixture : public BaseFixture
+class FakeNetworkInterfaceFixture : public TcpFactoryFixture
 {
 public:
   FakeNetworkInterfaceFixture()
@@ -322,7 +315,6 @@
 {
   using namespace boost::asio::ip;
 
-  TcpFactory factory;
   factory.prohibitEndpoint(tcp::Endpoint(address_v4::from_string("192.168.2.1"), 1024));
   BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
   BOOST_CHECK((factory.m_prohibitedEndpoints ==
diff --git a/tests/daemon/face/udp-factory.t.cpp b/tests/daemon/face/udp-factory.t.cpp
index b5ddb8a..0ad5612 100644
--- a/tests/daemon/face/udp-factory.t.cpp
+++ b/tests/daemon/face/udp-factory.t.cpp
@@ -36,12 +36,14 @@
 namespace face {
 namespace tests {
 
+using UdpFactoryFixture = FaceSystemFactoryFixture<UdpFactory>;
+
 BOOST_AUTO_TEST_SUITE(Face)
-BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, BaseFixture)
+BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, UdpFactoryFixture)
 
 using nfd::Face;
 
-BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceSystemFixture)
+BOOST_AUTO_TEST_SUITE(ProcessConfig)
 
 BOOST_AUTO_TEST_CASE(Channels)
 {
@@ -62,7 +64,6 @@
   parseConfig(CONFIG, true);
   parseConfig(CONFIG, false);
 
-  auto& factory = this->getFactoryById<UdpFactory>("udp");
   checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
 }
 
@@ -84,7 +85,6 @@
   parseConfig(CONFIG, true);
   parseConfig(CONFIG, false);
 
-  auto& factory = this->getFactoryById<UdpFactory>("udp");
   checkChannelListEqual(factory, {"udp4://0.0.0.0:7001"});
 }
 
@@ -106,11 +106,10 @@
   parseConfig(CONFIG, true);
   parseConfig(CONFIG, false);
 
-  auto& factory = this->getFactoryById<UdpFactory>("udp");
   checkChannelListEqual(factory, {"udp6://[::]:7001"});
 }
 
-class UdpMcastConfigFixture : public FaceSystemFixture
+class UdpMcastConfigFixture : public UdpFactoryFixture
 {
 protected:
   UdpMcastConfigFixture()
@@ -369,7 +368,6 @@
   parseConfig(CONFIG, true);
   parseConfig(CONFIG, false);
 
-  auto& factory = this->getFactoryById<UdpFactory>("udp");
   BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
   BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
 }
@@ -492,7 +490,6 @@
 
 BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  UdpFactory factory;
   BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
 
   std::vector<shared_ptr<const Channel>> expectedChannels;
@@ -511,8 +508,6 @@
 
 BOOST_AUTO_TEST_CASE(CreateChannel)
 {
-  UdpFactory factory;
-
   auto channel1 = factory.createChannel("127.0.0.1", "20070");
   auto channel1a = factory.createChannel("127.0.0.1", "20070");
   BOOST_CHECK_EQUAL(channel1, channel1a);
@@ -545,8 +540,6 @@
 
 BOOST_AUTO_TEST_CASE(CreateMulticastFace)
 {
-  UdpFactory factory;
-
   auto multicastFace1  = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
   auto multicastFace1a = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
   BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
@@ -599,8 +592,6 @@
 
 BOOST_AUTO_TEST_CASE(FaceCreate)
 {
-  UdpFactory factory;
-
   createFace(factory,
              FaceUri("udp4://127.0.0.1:6363"),
              {},
@@ -634,7 +625,6 @@
 
 BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
 {
-  UdpFactory factory;
   factory.createChannel("127.0.0.1", "20071");
 
   createFace(factory,
@@ -678,7 +668,7 @@
               "Local fields can only be enabled on faces with local scope"});
 }
 
-class FakeNetworkInterfaceFixture : public BaseFixture
+class FakeNetworkInterfaceFixture : public UdpFactoryFixture
 {
 public:
   FakeNetworkInterfaceFixture()
@@ -722,7 +712,6 @@
 {
   using namespace boost::asio::ip;
 
-  UdpFactory factory;
   factory.prohibitEndpoint(udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024));
   BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
   BOOST_CHECK((factory.m_prohibitedEndpoints ==
diff --git a/tests/daemon/face/unix-stream-factory.t.cpp b/tests/daemon/face/unix-stream-factory.t.cpp
index dc5b5ac..5bd0506 100644
--- a/tests/daemon/face/unix-stream-factory.t.cpp
+++ b/tests/daemon/face/unix-stream-factory.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -36,12 +36,14 @@
 #define CHANNEL_PATH1 "unix-stream-test.1.sock"
 #define CHANNEL_PATH2 "unix-stream-test.2.sock"
 
+using UnixStreamFactoryFixture = FaceSystemFactoryFixture<UnixStreamFactory>;
+
 BOOST_AUTO_TEST_SUITE(Face)
-BOOST_FIXTURE_TEST_SUITE(TestUnixStreamFactory, BaseFixture)
+BOOST_FIXTURE_TEST_SUITE(TestUnixStreamFactory, UnixStreamFactoryFixture)
 
 using nfd::Face;
 
-BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceSystemFixture)
+BOOST_AUTO_TEST_SUITE(ProcessConfig)
 
 BOOST_AUTO_TEST_CASE(Normal)
 {
@@ -97,8 +99,6 @@
 
 BOOST_AUTO_TEST_CASE(ChannelMap)
 {
-  UnixStreamFactory factory;
-
   shared_ptr<UnixStreamChannel> channel1 = factory.createChannel(CHANNEL_PATH1);
   shared_ptr<UnixStreamChannel> channel1a = factory.createChannel(CHANNEL_PATH1);
   BOOST_CHECK_EQUAL(channel1, channel1a);
@@ -113,7 +113,6 @@
 
 BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  UnixStreamFactory factory;
   BOOST_CHECK(factory.getChannels().empty());
 
   std::vector<shared_ptr<const Channel>> expectedChannels;
@@ -131,8 +130,6 @@
 
 BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
 {
-  UnixStreamFactory factory;
-
   createFace(factory,
              FaceUri("unix:///var/run/nfd.sock"),
              {},
diff --git a/tests/daemon/face/websocket-factory.t.cpp b/tests/daemon/face/websocket-factory.t.cpp
index 5243c97..c17e620 100644
--- a/tests/daemon/face/websocket-factory.t.cpp
+++ b/tests/daemon/face/websocket-factory.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -35,10 +35,12 @@
 
 namespace ip = boost::asio::ip;
 
-BOOST_AUTO_TEST_SUITE(Face)
-BOOST_FIXTURE_TEST_SUITE(TestWebSocketFactory, BaseFixture)
+using WebSocketFactoryFixture = FaceSystemFactoryFixture<WebSocketFactory>;
 
-BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceSystemFixture)
+BOOST_AUTO_TEST_SUITE(Face)
+BOOST_FIXTURE_TEST_SUITE(TestWebSocketFactory, WebSocketFactoryFixture)
+
+BOOST_AUTO_TEST_SUITE(ProcessConfig)
 
 BOOST_AUTO_TEST_CASE(Normal)
 {
@@ -58,7 +60,6 @@
   parseConfig(CONFIG, true);
   parseConfig(CONFIG, false);
 
-  auto& factory = this->getFactoryById<WebSocketFactory>("websocket");
   checkChannelListEqual(factory, {"ws://[::]:9696"});
 }
 
@@ -80,7 +81,6 @@
   parseConfig(CONFIG, true);
   parseConfig(CONFIG, false);
 
-  auto& factory = this->getFactoryById<WebSocketFactory>("websocket");
   checkChannelListEqual(factory, {"ws://0.0.0.0:9696"});
 }
 
@@ -137,7 +137,6 @@
     }
   )CONFIG";
 
-  auto& factory = this->getFactoryById<WebSocketFactory>("websocket");
   BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
 }
 
@@ -154,7 +153,6 @@
   )CONFIG";
 
   parseConfig(CONFIG1, false);
-  auto& factory = this->getFactoryById<WebSocketFactory>("websocket");
   checkChannelListEqual(factory, {"ws://[::]:9001"});
 
   const std::string CONFIG2 = R"CONFIG(
@@ -175,7 +173,6 @@
 
 BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  WebSocketFactory factory;
   BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
 
   std::vector<shared_ptr<const Channel>> expectedChannels;
@@ -194,8 +191,6 @@
 
 BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
 {
-  WebSocketFactory factory;
-
   createFace(factory,
              FaceUri("ws://127.0.0.1:20070"),
              {},
diff --git a/tests/daemon/mgmt/face-manager.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
index 52e2a11..90e99af 100644
--- a/tests/daemon/mgmt/face-manager.t.cpp
+++ b/tests/daemon/mgmt/face-manager.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -35,6 +35,7 @@
 #include <ndn-cxx/encoding/tlv-nfd.hpp>
 #include <ndn-cxx/mgmt/nfd/channel-status.hpp>
 #include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
+#include <ndn-cxx/net/network-monitor-stub.hpp>
 
 namespace nfd {
 namespace tests {
@@ -261,6 +262,11 @@
 class TestProtocolFactory : public face::ProtocolFactory
 {
 public:
+  TestProtocolFactory(const CtorParams& params)
+    : ProtocolFactory(params)
+  {
+  }
+
   void
   processConfig(OptionalConfigSection configSection,
                 FaceSystem::ConfigContext& context) final
@@ -298,7 +304,8 @@
 
 BOOST_AUTO_TEST_CASE(ChannelDataset)
 {
-  m_manager.m_faceSystem.m_factories["test"] = make_unique<TestProtocolFactory>();
+  m_manager.m_faceSystem.m_factories["test"] =
+    make_unique<TestProtocolFactory>(m_faceSystem.makePFCtorParams());
   auto factory = static_cast<TestProtocolFactory*>(m_manager.m_faceSystem.getFactoryById("test"));
 
   std::map<std::string, shared_ptr<TestChannel>> addedChannels;