diff --git a/daemon/main.cpp b/daemon/main.cpp
index d9867fe..541d8ff 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -11,6 +11,7 @@
 #include "mgmt/fib-manager.hpp"
 #include "mgmt/face-manager.hpp"
 #include "mgmt/local-control-header-manager.hpp"
+#include "mgmt/strategy-choice-manager.hpp"
 #include "face/tcp-factory.hpp"
 
 #ifdef HAVE_UNIX_SOCKETS
@@ -45,6 +46,7 @@
 static FibManager* g_fibManager;
 static FaceManager* g_faceManager;
 static LocalControlHeaderManager* g_localControlHeaderManager;
+static StrategyChoiceManager* g_strategyChoiceManager;
 static TcpFactory* g_tcpFactory;
 static shared_ptr<TcpChannel> g_tcpChannel;
 static shared_ptr<InternalFace> g_internalFace;
@@ -217,6 +219,9 @@
     new LocalControlHeaderManager(bind(&Forwarder::getFace, g_forwarder, _1),
                                   g_internalFace);
 
+  g_strategyChoiceManager = new StrategyChoiceManager(g_forwarder->getStrategyChoice(),
+                                                      g_internalFace);
+
   shared_ptr<fib::Entry> entry = g_forwarder->getFib().insert("/localhost/nfd").first;
   entry->addNextHop(g_internalFace, 0);
 }
diff --git a/daemon/mgmt/fib-manager.cpp b/daemon/mgmt/fib-manager.cpp
index 27707d7..8e27114 100644
--- a/daemon/mgmt/fib-manager.cpp
+++ b/daemon/mgmt/fib-manager.cpp
@@ -52,12 +52,6 @@
                      &FibManager::removeNextHop
                      ),
 
-    // Unsupported
-    // VerbAndProcessor(
-    //                  Name::Component("strategy"),
-    //                  &FibManager::strategy
-    //                  )
-
   };
 
 FibManager::FibManager(Fib& fib,
@@ -258,12 +252,6 @@
     }
 }
 
-void
-FibManager::strategy(const FibManagementOptions& options, ControlResponse& response)
-{
-
-}
-
 // void
 // FibManager::onConfig(ConfigFile::Node section, bool isDryRun)
 // {
diff --git a/daemon/mgmt/fib-manager.hpp b/daemon/mgmt/fib-manager.hpp
index 79be094..c7b7793 100644
--- a/daemon/mgmt/fib-manager.hpp
+++ b/daemon/mgmt/fib-manager.hpp
@@ -51,10 +51,6 @@
   removeNextHop(const FibManagementOptions& options,
                 ControlResponse& response);
 
-  void
-  strategy(const FibManagementOptions& options,
-           ControlResponse& response);
-
   bool
   extractOptions(const Interest& request,
                  FibManagementOptions& extractedOptions);
diff --git a/daemon/mgmt/strategy-choice-manager.cpp b/daemon/mgmt/strategy-choice-manager.cpp
new file mode 100644
index 0000000..00761dd
--- /dev/null
+++ b/daemon/mgmt/strategy-choice-manager.cpp
@@ -0,0 +1,169 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "strategy-choice-manager.hpp"
+#include "table/strategy-choice.hpp"
+#include "mgmt/app-face.hpp"
+
+namespace nfd {
+
+NFD_LOG_INIT("StrategyChoiceManager");
+
+const Name StrategyChoiceManager::COMMAND_PREFIX = "/localhost/nfd/strategy-choice";
+
+const size_t StrategyChoiceManager::COMMAND_UNSIGNED_NCOMPS =
+  StrategyChoiceManager::COMMAND_PREFIX.size() +
+  1 + // verb
+  1;  // verb options
+
+const size_t StrategyChoiceManager::COMMAND_SIGNED_NCOMPS =
+  StrategyChoiceManager::COMMAND_UNSIGNED_NCOMPS +
+  0; // No signed Interest support in mock, otherwise 4 (timestamp, nonce, signed info tlv, signature tlv)
+
+StrategyChoiceManager::StrategyChoiceManager(StrategyChoice& strategyChoice,
+                                             shared_ptr<AppFace> face)
+  : ManagerBase(face)
+  , m_strategyChoice(strategyChoice)
+{
+  face->setInterestFilter("/localhost/nfd/strategy-choice",
+                          bind(&StrategyChoiceManager::onStrategyChoiceRequest, this, _2));
+}
+
+StrategyChoiceManager::~StrategyChoiceManager()
+{
+
+}
+
+void
+StrategyChoiceManager::onStrategyChoiceRequest(const Interest& request)
+{
+  const Name& command = request.getName();
+  const size_t commandNComps = command.size();
+
+  if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
+      commandNComps < COMMAND_SIGNED_NCOMPS)
+    {
+      NFD_LOG_INFO("command result: unsigned verb: " << command);
+      sendResponse(command, 401, "Signature required");
+
+      return;
+    }
+  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
+           !COMMAND_PREFIX.isPrefixOf(command))
+    {
+      NFD_LOG_INFO("command result: malformed");
+      sendResponse(command, 400, "Malformed command");
+      return;
+    }
+
+  onValidatedStrategyChoiceRequest(request.shared_from_this());
+}
+
+void
+StrategyChoiceManager::onValidatedStrategyChoiceRequest(const shared_ptr<const Interest>& request)
+{
+  static const Name::Component VERB_SET("set");
+  static const Name::Component VERB_UNSET("unset");
+
+  const Name& command = request->getName();
+
+  ndn::nfd::FibManagementOptions options;
+  if (!extractOptions(*request, options))
+    {
+      sendResponse(command, 400, "Malformed command");
+      return;
+    }
+
+  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
+  ControlResponse response;
+  if (verb == VERB_SET)
+    {
+      setStrategy(options, response);
+    }
+  else if (verb == VERB_UNSET)
+    {
+      unsetStrategy(options, response);
+    }
+  else
+    {
+      NFD_LOG_INFO("command result: unsupported verb: " << verb);
+      setResponse(response, 501, "Unsupported command");
+    }
+  sendResponse(command, response);
+}
+
+bool
+StrategyChoiceManager::extractOptions(const Interest& request,
+                                      ndn::nfd::FibManagementOptions& extractedOptions)
+{
+  const Name& command = request.getName();
+  const size_t optionCompIndex =
+    COMMAND_PREFIX.size() + 1;
+
+  try
+    {
+      Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
+      extractedOptions.wireDecode(rawOptions);
+    }
+  catch (const ndn::Tlv::Error& e)
+    {
+      NFD_LOG_INFO("Bad command option parse: " << command);
+      return false;
+    }
+
+  NFD_LOG_DEBUG("Options parsed OK");
+  return true;
+}
+
+void
+StrategyChoiceManager::setStrategy(const ndn::nfd::FibManagementOptions& options,
+                                   ControlResponse& response)
+{
+  const Name& prefix = options.getName();
+  const Name& selectedStrategy = options.getStrategy();
+
+  if (!m_strategyChoice.hasStrategy(selectedStrategy))
+    {
+      NFD_LOG_INFO("strategy-choice result: FAIL reason: unknown-strategy: "
+                   << options.getStrategy());
+      setResponse(response, 504, "Unsupported strategy");
+      return;
+    }
+
+  if (m_strategyChoice.insert(prefix, selectedStrategy))
+    {
+      setResponse(response, 200, "Success", options.wireEncode());
+    }
+  else
+    {
+      setResponse(response, 405, "Strategy not installed");
+    }
+}
+
+void
+StrategyChoiceManager::unsetStrategy(const ndn::nfd::FibManagementOptions& options,
+                                     ControlResponse& response)
+{
+  static const Name ROOT_PREFIX;
+
+  const Name& prefix = options.getName();
+  if (prefix == ROOT_PREFIX)
+    {
+      NFD_LOG_INFO("strategy-choice result: FAIL reason: unknown-prefix: "
+                   << options.getName());
+      setResponse(response, 403, "Cannot unset root prefix strategy");
+      return;
+    }
+
+  m_strategyChoice.erase(prefix);
+  setResponse(response, 200, "Success", options.wireEncode());
+}
+
+
+
+} // namespace nfd
+
+
diff --git a/daemon/mgmt/strategy-choice-manager.hpp b/daemon/mgmt/strategy-choice-manager.hpp
new file mode 100644
index 0000000..34046ac
--- /dev/null
+++ b/daemon/mgmt/strategy-choice-manager.hpp
@@ -0,0 +1,68 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_MGMT_STRATEGY_CHOICE_MANAGER_HPP
+#define NFD_MGMT_STRATEGY_CHOICE_MANAGER_HPP
+
+#include "mgmt/manager-base.hpp"
+
+#include <ndn-cpp-dev/management/nfd-fib-management-options.hpp>
+
+namespace nfd {
+
+const std::string STRATEGY_CHOICE_PRIVILEGE = "strategy-choice";
+
+class StrategyChoice;
+
+class StrategyChoiceManager : public ManagerBase
+{
+public:
+  StrategyChoiceManager(StrategyChoice& strategyChoice,
+                        shared_ptr<AppFace> face);
+
+  virtual
+  ~StrategyChoiceManager();
+
+  void
+  onStrategyChoiceRequest(const Interest& request);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  void
+  onValidatedStrategyChoiceRequest(const shared_ptr<const Interest>& request);
+
+  bool
+  extractOptions(const Interest& request,
+                   ndn::nfd::FibManagementOptions& extractedOptions);
+
+
+
+  void
+  setStrategy(const ndn::nfd::FibManagementOptions& options,
+              ControlResponse& response);
+
+  void
+  unsetStrategy(const ndn::nfd::FibManagementOptions& options,
+                ControlResponse& response);
+private:
+
+  StrategyChoice& m_strategyChoice;
+
+  static const Name COMMAND_PREFIX; // /localhost/nfd/strategy-choice
+
+  // number of components in an invalid, but not malformed, unsigned command.
+  // (/localhost/nfd/strategy-choice + verb + options) = 5
+  static const size_t COMMAND_UNSIGNED_NCOMPS;
+
+  // number of components in a valid signed Interest.
+  // (see UNSIGNED_NCOMPS), 9 with signed Interest support.
+  static const size_t COMMAND_SIGNED_NCOMPS;
+
+};
+
+} // namespace nfd
+
+#endif // NFD_MGMT_STRATEGY_CHOICE_MANAGER_HPP
+
diff --git a/tests/mgmt/strategy-choice-manager.cpp b/tests/mgmt/strategy-choice-manager.cpp
new file mode 100644
index 0000000..e2285c2
--- /dev/null
+++ b/tests/mgmt/strategy-choice-manager.cpp
@@ -0,0 +1,427 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "mgmt/strategy-choice-manager.hpp"
+#include "face/face.hpp"
+#include "mgmt/internal-face.hpp"
+#include "table/name-tree.hpp"
+#include "table/strategy-choice.hpp"
+#include "fw/forwarder.hpp"
+#include "fw/strategy.hpp"
+#include "tests/face/dummy-face.hpp"
+
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("StrategyChoiceManagerTest");
+
+class DummyStrategy : public fw::Strategy
+{
+public:
+  DummyStrategy(Forwarder& forwarder, const Name& strategyName)
+    : fw::Strategy(forwarder, strategyName)
+  {
+
+  }
+
+  virtual
+  ~DummyStrategy()
+  {
+
+  }
+
+  virtual void
+  afterReceiveInterest(const Face& inFace,
+                       const Interest& interest,
+                       shared_ptr<fib::Entry> fibEntry,
+                       shared_ptr<pit::Entry> pitEntry)
+  {
+
+  }
+};
+
+class TestStrategyA : public DummyStrategy
+{
+public:
+  TestStrategyA(Forwarder& forwarder)
+    : DummyStrategy(forwarder, "/localhost/nfd/strategy/test-strategy-a")
+  {
+  }
+
+  virtual
+  ~TestStrategyA()
+  {
+
+  }
+};
+
+class TestStrategyB : public DummyStrategy
+{
+public:
+  TestStrategyB(Forwarder& forwarder)
+    : DummyStrategy(forwarder, "/localhost/nfd/strategy/test-strategy-b")
+  {
+  }
+
+  virtual
+  ~TestStrategyB()
+  {
+
+  }
+};
+
+class StrategyChoiceManagerFixture : protected BaseFixture
+{
+public:
+
+  StrategyChoiceManagerFixture()
+    : m_nameTree(1024)
+    , m_strategyChoice(m_nameTree, make_shared<TestStrategyA>(boost::ref(m_forwarder)))
+    , m_face(make_shared<InternalFace>())
+    , m_manager(m_strategyChoice, m_face)
+    , m_callbackFired(false)
+  {
+
+  }
+
+  void
+  validateControlResponseCommon(const Data& response,
+                                const Name& expectedName,
+                                uint32_t expectedCode,
+                                const std::string& expectedText,
+                                ControlResponse& control)
+  {
+    m_callbackFired = true;
+    Block controlRaw = response.getContent().blockFromValue();
+
+    control.wireDecode(controlRaw);
+
+    NFD_LOG_DEBUG("received control response"
+                  << " Name: " << response.getName()
+                  << " code: " << control.getCode()
+                  << " text: " << control.getText());
+
+    BOOST_CHECK_EQUAL(response.getName(), expectedName);
+    BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
+    BOOST_CHECK_EQUAL(control.getText(), expectedText);
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    if (!control.getBody().empty())
+      {
+        BOOST_FAIL("found unexpected control response body");
+      }
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText,
+                          const Block& expectedBody)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    BOOST_REQUIRE(!control.getBody().empty());
+    BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
+
+    BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
+                       expectedBody.value_size()) == 0);
+
+  }
+
+  bool
+  didCallbackFire()
+  {
+    return m_callbackFired;
+  }
+
+  void
+  resetCallbackFired()
+  {
+    m_callbackFired = false;
+  }
+
+  shared_ptr<InternalFace>&
+  getFace()
+  {
+    return m_face;
+  }
+
+  StrategyChoiceManager&
+  getManager()
+  {
+    return m_manager;
+  }
+
+  StrategyChoice&
+  getStrategyChoice()
+  {
+    return m_strategyChoice;
+  }
+
+protected:
+  Forwarder m_forwarder;
+  NameTree m_nameTree;
+  StrategyChoice m_strategyChoice;
+  shared_ptr<InternalFace> m_face;
+  StrategyChoiceManager m_manager;
+
+private:
+  bool m_callbackFired;
+};
+
+class AllStrategiesFixture : public StrategyChoiceManagerFixture
+{
+public:
+  AllStrategiesFixture()
+  {
+    m_strategyChoice.install(make_shared<TestStrategyB>(boost::ref(m_forwarder)));
+  }
+
+  virtual
+  ~AllStrategiesFixture()
+  {
+
+  }
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtStrategyChoiceManager, AllStrategiesFixture)
+
+BOOST_AUTO_TEST_CASE(TestFireInterestFilter)
+{
+  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this,  _1,
+         command->getName(), 400, "Malformed command");
+
+  getFace()->sendInterest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(MalformedCommmand)
+{
+  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getManager().onStrategyChoiceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(UnsupportedVerb)
+{
+  ndn::nfd::FibManagementOptions options;
+  options.setStrategy("/localhost/nfd/strategy/test-strategy-b");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("unsupported");
+  commandName.append(encodedOptions);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 501, "Unsupported command");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(BadOptionParse)
+{
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append("NotReallyOptions");
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(SetStrategies)
+{
+  ndn::nfd::FibManagementOptions options;
+  options.setName("/test");
+  options.setStrategy("/localhost/nfd/strategy/test-strategy-b");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append(encodedOptions);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 200, "Success", encodedOptions);
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
+  BOOST_REQUIRE_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-b");
+
+  resetCallbackFired();
+  getFace()->onReceiveData.clear();
+}
+
+BOOST_AUTO_TEST_CASE(SetUnsupportedStrategy)
+{
+  ndn::nfd::FibManagementOptions options;
+  options.setName("/test");
+  options.setStrategy("/localhost/nfd/strategy/unit-test-doesnotexist");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append(encodedOptions);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 504, "Unsupported strategy");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
+  BOOST_CHECK_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-a");
+}
+
+class DefaultStrategyOnlyFixture : public StrategyChoiceManagerFixture
+{
+public:
+  DefaultStrategyOnlyFixture()
+    : StrategyChoiceManagerFixture()
+  {
+
+  }
+
+  virtual
+  ~DefaultStrategyOnlyFixture()
+  {
+
+  }
+};
+
+
+/// \todo I'm not sure this code branch (code 405) can happen. The manager tests for the strategy first and will return 504.
+// BOOST_FIXTURE_TEST_CASE(SetNotInstalled, DefaultStrategyOnlyFixture)
+// {
+//   BOOST_REQUIRE(!getStrategyChoice().hasStrategy("/localhost/nfd/strategy/test-strategy-b"));
+//   ndn::nfd::FibManagementOptions options;
+//   options.setName("/test");
+//   options.setStrategy("/localhost/nfd/strategy/test-strategy-b");
+
+//   Block encodedOptions(options.wireEncode());
+
+//   Name commandName("/localhost/nfd/strategy-choice");
+//   commandName.append("set");
+//   commandName.append(encodedOptions);
+
+//   shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+//   getFace()->onReceiveData +=
+//     bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+//          command->getName(), 405, "Strategy not installed");
+
+//   getManager().onValidatedStrategyChoiceRequest(command);
+
+//   BOOST_REQUIRE(didCallbackFire());
+//   fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
+//   BOOST_CHECK_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-a");
+// }
+
+BOOST_AUTO_TEST_CASE(Unset)
+{
+  ndn::nfd::FibManagementOptions options;
+  options.setName("/test");
+
+  BOOST_REQUIRE(m_strategyChoice.insert("/test", "/localhost/nfd/strategy/test-strategy-b"));
+  BOOST_REQUIRE_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
+                      "/localhost/nfd/strategy/test-strategy-b");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("unset");
+  commandName.append(encodedOptions);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 200, "Success", encodedOptions);
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+
+  BOOST_CHECK_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
+                    "/localhost/nfd/strategy/test-strategy-a");
+}
+
+BOOST_AUTO_TEST_CASE(UnsetRoot)
+{
+  ndn::nfd::FibManagementOptions options;
+  options.setName("/");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("unset");
+  commandName.append(encodedOptions);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 403, "Cannot unset root prefix strategy");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+
+  BOOST_CHECK_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
+                    "/localhost/nfd/strategy/test-strategy-a");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
