diff --git a/tests/unit-tests/management/nfd-status-dataset.t.cpp b/tests/unit-tests/management/nfd-status-dataset.t.cpp
new file mode 100644
index 0000000..63b98aa
--- /dev/null
+++ b/tests/unit-tests/management/nfd-status-dataset.t.cpp
@@ -0,0 +1,387 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "management/nfd-status-dataset.hpp"
+#include "management/nfd-controller.hpp"
+
+#include "nfd-controller-fixture.hpp"
+#include "../make-interest-data.hpp"
+
+namespace ndn {
+namespace nfd {
+namespace tests {
+
+using ndn::util::makeData;
+using ndn::util::signData;
+
+BOOST_AUTO_TEST_SUITE(Management)
+
+class ControllerStatusDatasetFixture : public ControllerFixture
+{
+protected:
+  /** \brief send one WireEncodable as Data reply
+   *  \param prefix dataset prefix without version and segment
+   *  \param payload payload block
+   *  \note payload must fit in one Data
+   */
+  template<typename T>
+  void
+  sendDataset(const Name& prefix, const T& payload)
+  {
+    BOOST_CONCEPT_ASSERT((WireEncodable<T>));
+
+    auto data = this->prepareDatasetReply(prefix);
+    data->setContent(payload.wireEncode());
+    face.receive(*signData(data));
+  }
+
+  /** \brief send two WireEncodables as Data reply
+   *  \param prefix dataset prefix without version and segment
+   *  \param payload1 first vector item
+   *  \param payload2 second vector item
+   *  \note all payloads must fit in one Data
+   */
+  template<typename T1, typename T2>
+  void
+  sendDataset(const Name& prefix, const T1& payload1, const T2& payload2)
+  {
+    // The test suite allows up to two items, and put them in the same Data packet,
+    // because this test suite focuses on Controller::fetch<StatusDataset>,
+    // and is not intended to cover SegmentFetcher behavior.
+
+    BOOST_CONCEPT_ASSERT((WireEncodable<T1>));
+    BOOST_CONCEPT_ASSERT((WireEncodable<T2>));
+
+    ndn::encoding::EncodingBuffer buffer;
+    payload2.wireEncode(buffer);
+    payload1.wireEncode(buffer);
+
+    auto data = this->prepareDatasetReply(prefix);
+    data->setContent(buffer.buf(), buffer.size());
+    face.receive(*signData(data));
+  }
+
+private:
+  shared_ptr<Data>
+  prepareDatasetReply(const Name& prefix)
+  {
+    Name name = prefix;
+    name.appendVersion().appendSegment(0);
+
+    // These warnings assist in debugging a `hasResult` check failure.
+    // They usually indicate a misspelled prefix or incorrect timing in the test case.
+    if (face.sentInterests.size() < 1) {
+      BOOST_WARN_MESSAGE(false, "no Interest expressed");
+    }
+    else {
+      BOOST_WARN_MESSAGE(face.sentInterests.back().getName().isPrefixOf(name),
+                         "last Interest " << face.sentInterests.back().getName() <<
+                         " cannot be satisfied by this Data " << name);
+    }
+
+    auto data = make_shared<Data>(name);
+    data->setFinalBlockId(data->getName()[-1]);
+    return data;
+  }
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestNfdStatusDataset, ControllerStatusDatasetFixture)
+
+BOOST_AUTO_TEST_SUITE(Failures)
+
+BOOST_AUTO_TEST_CASE(Timeout)
+{
+  CommandOptions options;
+  options.setTimeout(time::milliseconds(3000));
+  controller.fetch<FaceDataset>(
+    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
+    failCallback,
+    options);
+  this->advanceClocks(time::milliseconds(500), 7);
+
+  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
+  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_TIMEOUT);
+}
+
+BOOST_AUTO_TEST_CASE(DataHasNoSegment)
+{
+  controller.fetch<FaceDataset>(
+    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  face.receive(*makeData("/localhost/nfd/faces/list/%FD%00"));
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
+  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_SERVER);
+}
+
+BOOST_AUTO_TEST_CASE(Nack)
+{
+  controller.fetch<FaceDataset>(
+    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+  face.receive(lp::Nack(face.sentInterests.back()));
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
+  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_NACK);
+}
+
+BOOST_AUTO_TEST_CASE(ParseError1)
+{
+  controller.fetch<FaceDataset>(
+    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  Name payload; // Name is not valid FaceStatus
+  this->sendDataset("/localhost/nfd/faces/list", payload);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
+  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_SERVER);
+}
+
+BOOST_AUTO_TEST_CASE(ParseError2)
+{
+  controller.fetch<FaceDataset>(
+    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  FaceStatus payload1;
+  payload1.setFaceId(10930);
+  Name payload2; // Name is not valid FaceStatus
+  this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
+  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_SERVER);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Failures
+
+BOOST_AUTO_TEST_SUITE(Datasets)
+
+BOOST_AUTO_TEST_CASE(StatusGeneral)
+{
+  bool hasResult = false;
+  controller.fetch<ForwarderGeneralStatusDataset>(
+    [&hasResult] (const ForwarderStatus& result) {
+      hasResult = true;
+      BOOST_CHECK_EQUAL(result.getNfdVersion(), "0.4.2");
+    },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  ForwarderStatus payload;
+  payload.setNfdVersion("0.4.2");
+  this->sendDataset("/localhost/nfd/status/general", payload);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_CHECK(hasResult);
+  BOOST_CHECK_EQUAL(failCodes.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(FaceList)
+{
+  bool hasResult = false;
+  controller.fetch<FaceDataset>(
+    [&hasResult] (const std::vector<FaceStatus>& result) {
+      hasResult = true;
+      BOOST_CHECK_EQUAL(result.size(), 2);
+      BOOST_CHECK_EQUAL(result.front().getFaceId(), 24485);
+    },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  FaceStatus payload1;
+  payload1.setFaceId(24485);
+  FaceStatus payload2;
+  payload2.setFaceId(12987);
+  this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_CHECK(hasResult);
+  BOOST_CHECK_EQUAL(failCodes.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(FaceQuery)
+{
+  FaceQueryFilter filter;
+  filter.setUriScheme("udp4");
+  bool hasResult = false;
+  controller.fetch<FaceQueryDataset>(
+    filter,
+    [&hasResult] (const std::vector<FaceStatus>& result) {
+      hasResult = true;
+      BOOST_CHECK_EQUAL(result.size(), 1);
+      BOOST_CHECK_EQUAL(result.front().getFaceId(), 8795);
+    },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  Name prefix("/localhost/nfd/faces/query");
+  prefix.append(filter.wireEncode());
+  FaceStatus payload;
+  payload.setFaceId(8795);
+  this->sendDataset(prefix, payload);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_CHECK(hasResult);
+  BOOST_CHECK_EQUAL(failCodes.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(FaceQueryWithOptions)
+{
+  FaceQueryFilter filter;
+  filter.setUriScheme("udp4");
+  CommandOptions options;
+  options.setTimeout(time::milliseconds(3000));
+  bool hasResult = false;
+  controller.fetch<FaceQueryDataset>(
+    filter,
+    [&hasResult] (const std::vector<FaceStatus>& result) {
+      hasResult = true;
+      BOOST_CHECK_EQUAL(result.size(), 1);
+      BOOST_CHECK_EQUAL(result.front().getFaceId(), 14022);
+    },
+    failCallback,
+    options);
+  this->advanceClocks(time::milliseconds(500));
+
+  Name prefix("/localhost/nfd/faces/query");
+  prefix.append(filter.wireEncode());
+  FaceStatus payload;
+  payload.setFaceId(14022);
+  this->sendDataset(prefix, payload);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_CHECK(hasResult);
+  BOOST_CHECK_EQUAL(failCodes.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(FibList)
+{
+  bool hasResult = false;
+  controller.fetch<FibDataset>(
+    [&hasResult] (const std::vector<FibEntry>& result) {
+      hasResult = true;
+      BOOST_CHECK_EQUAL(result.size(), 2);
+      BOOST_CHECK_EQUAL(result.front().getPrefix(), "/wYs7fzYcfG");
+    },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  FibEntry payload1;
+  payload1.setPrefix("/wYs7fzYcfG");
+  FibEntry payload2;
+  payload2.setPrefix("/LKvmnzY5S");
+  this->sendDataset("/localhost/nfd/fib/list", payload1, payload2);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_CHECK(hasResult);
+  BOOST_CHECK_EQUAL(failCodes.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(StrategyChoiceList)
+{
+  bool hasResult = false;
+  controller.fetch<StrategyChoiceDataset>(
+    [&hasResult] (const std::vector<StrategyChoice>& result) {
+      hasResult = true;
+      BOOST_CHECK_EQUAL(result.size(), 2);
+      BOOST_CHECK_EQUAL(result.front().getName(), "/8MLz6N3B");
+    },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  StrategyChoice payload1;
+  payload1.setName("/8MLz6N3B");
+  StrategyChoice payload2;
+  payload2.setName("/svqcBu0YwU");
+  this->sendDataset("/localhost/nfd/strategy-choice/list", payload1, payload2);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_CHECK(hasResult);
+  BOOST_CHECK_EQUAL(failCodes.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(RibList)
+{
+  bool hasResult = false;
+  controller.fetch<RibDataset>(
+    [&hasResult] (const std::vector<RibEntry>& result) {
+      hasResult = true;
+      BOOST_CHECK_EQUAL(result.size(), 2);
+      BOOST_CHECK_EQUAL(result.front().getName(), "/zXxBth97ee");
+    },
+    failCallback);
+  this->advanceClocks(time::milliseconds(500));
+
+  RibEntry payload1;
+  payload1.setName("/zXxBth97ee");
+  RibEntry payload2;
+  payload2.setName("/rJ8CvUpr4G");
+  this->sendDataset("/localhost/nfd/rib/list", payload1, payload2);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_CHECK(hasResult);
+  BOOST_CHECK_EQUAL(failCodes.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(RibListWithOptions)
+{
+  CommandOptions options;
+  options.setPrefix("/localhop/nfd");
+  bool hasResult = false;
+  controller.fetch<RibDataset>(
+    [&hasResult] (const std::vector<RibEntry>& result) {
+      hasResult = true;
+      BOOST_CHECK_EQUAL(result.size(), 1);
+      BOOST_CHECK_EQUAL(result.front().getName(), "/e6L5K4ascd");
+    },
+    failCallback,
+    options);
+  this->advanceClocks(time::milliseconds(500));
+
+  RibEntry payload;
+  payload.setName("/e6L5K4ascd");
+  this->sendDataset("/localhop/nfd/rib/list", payload);
+  this->advanceClocks(time::milliseconds(500));
+
+  BOOST_CHECK(hasResult);
+  BOOST_CHECK_EQUAL(failCodes.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Datasets
+
+BOOST_AUTO_TEST_SUITE_END() // TestNfdStatusDataset
+BOOST_AUTO_TEST_SUITE_END() // Management
+
+} // namespace tests
+} // namespace nfd
+} // namespace ndn
