diff --git a/tests/unit/clients/iterative-query-controller.t.cpp b/tests/unit/clients/iterative-query-controller.t.cpp
new file mode 100644
index 0000000..6478156
--- /dev/null
+++ b/tests/unit/clients/iterative-query-controller.t.cpp
@@ -0,0 +1,139 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2020, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "clients/iterative-query-controller.hpp"
+#include "daemon/name-server.hpp"
+
+#include "boost-test.hpp"
+#include "unit/database-test-data.hpp"
+
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+namespace ndn {
+namespace ndns {
+namespace tests {
+
+class QueryControllerFixture : public DbTestData
+{
+public:
+  QueryControllerFixture()
+    : producerFace(io, {false, true})
+    , consumerFace(io, {true, true})
+    , validator(NdnsValidatorBuilder::create(producerFace))
+    , top(m_test.getName(), m_certName, producerFace, m_session, m_keyChain, *validator)
+    , net(m_net.getName(), m_certName, producerFace, m_session, m_keyChain, *validator)
+    , ndnsim(m_ndnsim.getName(), m_certName, producerFace, m_session, m_keyChain, *validator)
+  {
+    run();
+    producerFace.onSendInterest.connect([this] (const Interest& interest) {
+      io.post([=] { consumerFace.receive(interest); });
+    });
+    consumerFace.onSendInterest.connect([this] (const Interest& interest) {
+      io.post([=] { producerFace.receive(interest); });
+    });
+    producerFace.onSendData.connect([this] (const Data& data) {
+      io.post([=] { consumerFace.receive(data); });
+    });
+    consumerFace.onSendData.connect([this] (const Data& data) {
+      io.post([=] { producerFace.receive(data); });
+    });
+  }
+
+  void
+  run()
+  {
+    io.poll();
+    io.reset();
+  }
+
+public:
+  boost::asio::io_service io;
+  ndn::util::DummyClientFace producerFace;
+  ndn::util::DummyClientFace consumerFace;
+
+  unique_ptr<security::Validator> validator;
+  ndns::NameServer top;
+  ndns::NameServer net;
+  ndns::NameServer ndnsim;
+};
+
+
+BOOST_AUTO_TEST_SUITE(IterativeQueryController)
+
+BOOST_FIXTURE_TEST_CASE(Basic, QueryControllerFixture)
+{
+  using std::string;
+  using ndns::NameServer;
+
+  Name name = m_ndnsim.getName();
+  Name dstLabel(name.append("www"));
+  name::Component rrType("TXT");
+  time::milliseconds lifetime(4000);
+
+  bool hasDataBack = false;
+  auto ctr = std::make_shared<ndns::IterativeQueryController>(
+    dstLabel, rrType, lifetime,
+    [&hasDataBack] (const Data&, const Response&) {
+      hasDataBack = true;
+      BOOST_CHECK(true);
+    },
+    [] (uint32_t errCode, const std::string& errMsg) {
+      BOOST_CHECK(false);
+    },
+    consumerFace);
+
+  // IterativeQueryController is a whole process
+  // the tester should not send Interest one by one
+  // instead of starting it and letting it handle Interest/Data automatically
+  ctr->setStartComponentIndex(1);
+
+  ctr->start();
+
+  run();
+
+  BOOST_CHECK_EQUAL(hasDataBack, true);
+
+  const std::vector<Interest>& interestRx = consumerFace.sentInterests;
+  BOOST_CHECK_EQUAL(interestRx.size(), 4);
+
+  std::vector<std::string> interestNames =
+    {
+      "/test19/NDNS/net/NS",
+      "/test19/net/NDNS/ndnsim/NS",
+      "/test19/net/ndnsim/NDNS/www/NS",
+      "/test19/net/ndnsim/NDNS/www/TXT"
+    };
+  for (int i = 0; i < 4; i++) {
+    // check if NDNS do iterative-query with right names
+    BOOST_CHECK_EQUAL(interestRx[i].getName(), Name(interestNames[i]));
+    // except for the first one, interest sent should has a Link object
+    if (i > 0) {
+      BOOST_CHECK_EQUAL(!interestRx[i].getForwardingHint().empty(), true);
+      if (!interestRx[i].getForwardingHint().empty()) {
+        BOOST_CHECK_EQUAL(interestRx[i].getForwardingHint(), m_links[i - 1].getDelegationList());
+      }
+    }
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace ndns
+} // namespace ndn
