diff --git a/tests/route/test-routing-calculator-link-state.cpp b/tests/route/test-routing-calculator-link-state.cpp
index dce29c5..5f38703 100644
--- a/tests/route/test-routing-calculator-link-state.cpp
+++ b/tests/route/test-routing-calculator-link-state.cpp
@@ -37,13 +37,26 @@
 static const ndn::Name ROUTER_A_NAME = "/ndn/site/%C1.Router/this-router";
 static const ndn::Name ROUTER_B_NAME = "/ndn/site/%C1.Router/b";
 static const ndn::Name ROUTER_C_NAME = "/ndn/site/%C1.Router/c";
-static const ndn::FaceUri ROUTER_A_FACE("udp4://10.0.0.1");
-static const ndn::FaceUri ROUTER_B_FACE("udp4://10.0.0.2");
-static const ndn::FaceUri ROUTER_C_FACE("udp4://10.0.0.3");
-constexpr double LINK_AB_COST = 5;
-constexpr double LINK_AC_COST = 10;
-constexpr double LINK_BC_COST = 17;
+static const ndn::FaceUri ROUTER_A_FACE("udp4://10.0.0.1:6363");
+static const ndn::FaceUri ROUTER_B_FACE("udp4://10.0.0.2:6363");
+static const ndn::FaceUri ROUTER_C_FACE("udp4://10.0.0.3:6363");
+constexpr double LINK_AB_COST = 5.0;
+constexpr double LINK_AC_COST = 10.0;
+constexpr double LINK_BC_COST = 17.0;
 
+/**
+ * @brief Provide a topology for link-state routing calculator testing.
+ *
+ * The topology consists of three routers: A, B, C.
+ * After calling all three setupRouter functions, they will form a triangle topology:
+ *
+ *   A-----B
+ *    \   /
+ *     \ /
+ *      C
+ *
+ * The local router, as reported by `conf.getRouterPrefix()`, is router A.
+ */
 class LinkStateCalculatorFixture : public IoKeyChainFixture
 {
 public:
@@ -55,51 +68,93 @@
     , routingTable(nlsr.m_routingTable)
     , lsdb(nlsr.m_lsdb)
   {
-    setUpTopology();
   }
 
-  // Triangle topology with routers A, B, C connected
-  void setUpTopology()
+  /**
+   * @brief Insert Adjacency LSA of router A into LSDB.
+   */
+  void
+  setupRouterA(double costAB = LINK_AB_COST, double costAC = LINK_AC_COST)
   {
-    Adjacent a(ROUTER_A_NAME, ROUTER_A_FACE, 0, Adjacent::STATUS_ACTIVE, 0, 0);
-    Adjacent b(ROUTER_B_NAME, ROUTER_B_FACE, 0, Adjacent::STATUS_ACTIVE, 0, 0);
-    Adjacent c(ROUTER_C_NAME, ROUTER_C_FACE, 0, Adjacent::STATUS_ACTIVE, 0, 0);
+    AdjacencyList& adjList = conf.getAdjacencyList();
+    if (!std::isnan(costAB)) {
+      adjList.insert(Adjacent(ROUTER_B_NAME, ROUTER_B_FACE, costAB, Adjacent::STATUS_ACTIVE, 0, 0));
+    }
+    if (!std::isnan(costAC)) {
+      adjList.insert(Adjacent(ROUTER_C_NAME, ROUTER_C_FACE, costAC, Adjacent::STATUS_ACTIVE, 0, 0));
+    }
 
-    // Router A
-    b.setLinkCost(LINK_AB_COST);
-    c.setLinkCost(LINK_AC_COST);
+    lsdb.installLsa(std::make_shared<AdjLsa>(ROUTER_A_NAME, 1, MAX_TIME, adjList));
+  }
 
-    AdjacencyList& adjacencyListA = conf.getAdjacencyList();
-    adjacencyListA.insert(b);
-    adjacencyListA.insert(c);
+  /**
+   * @brief Insert Adjacency LSA of router B into LSDB.
+   */
+  void
+  setupRouterB(double costBC = LINK_BC_COST, double costBA = LINK_AB_COST)
+  {
+    AdjacencyList adjList;
+    if (!std::isnan(costBC)) {
+      adjList.insert(Adjacent(ROUTER_C_NAME, ROUTER_C_FACE, costBC, Adjacent::STATUS_ACTIVE, 0, 0));
+    }
+    if (!std::isnan(costBA)) {
+      adjList.insert(Adjacent(ROUTER_A_NAME, ROUTER_A_FACE, costBA, Adjacent::STATUS_ACTIVE, 0, 0));
+    }
 
-    AdjLsa adjA(a.getName(), 1, MAX_TIME, adjacencyListA);
-    lsdb.installLsa(std::make_shared<AdjLsa>(adjA));
+    lsdb.installLsa(std::make_shared<AdjLsa>(ROUTER_B_NAME, 1, MAX_TIME, adjList));
+  }
 
-    // Router B
-    a.setLinkCost(LINK_AB_COST);
-    c.setLinkCost(LINK_BC_COST);
+  /**
+   * @brief Insert Adjacency LSA of router C into LSDB.
+   */
+  void
+  setupRouterC(double costCA = LINK_AC_COST, double costCB = LINK_BC_COST)
+  {
+    AdjacencyList adjList;
+    if (!std::isnan(costCA)) {
+      adjList.insert(Adjacent(ROUTER_A_NAME, ROUTER_A_FACE, costCA, Adjacent::STATUS_ACTIVE, 0, 0));
+    }
+    if (!std::isnan(costCB)) {
+      adjList.insert(Adjacent(ROUTER_B_NAME, ROUTER_B_FACE, costCB, Adjacent::STATUS_ACTIVE, 0, 0));
+    }
 
-    AdjacencyList adjacencyListB;
-    adjacencyListB.insert(a);
-    adjacencyListB.insert(c);
+    lsdb.installLsa(std::make_shared<AdjLsa>(ROUTER_C_NAME, 1, MAX_TIME, adjList));
+  }
 
-    AdjLsa adjB(b.getName(), 1, MAX_TIME, adjacencyListB);
-    lsdb.installLsa(std::make_shared<AdjLsa>(adjB));
-
-    // Router C
-    a.setLinkCost(LINK_AC_COST);
-    b.setLinkCost(LINK_BC_COST);
-
-    AdjacencyList adjacencyListC;
-    adjacencyListC.insert(a);
-    adjacencyListC.insert(b);
-
-    AdjLsa adjC(c.getName(), 1, MAX_TIME, adjacencyListC);
-    lsdb.installLsa(std::make_shared<AdjLsa>(adjC));
-
+  /**
+   * @brief Run link-state routing calculator.
+   */
+  void
+  calculatePath()
+  {
     auto lsaRange = lsdb.getLsdbIterator<AdjLsa>();
-    map = NameMap::createFromAdjLsdb(lsaRange.first, lsaRange.second);
+    NameMap map = NameMap::createFromAdjLsdb(lsaRange.first, lsaRange.second);
+    calculateLinkStateRoutingPath(map, routingTable, conf, lsdb);
+  }
+
+  /**
+   * @brief Verify that the routing table contains an entry with specific next hops.
+   * @param destination Destination router.
+   * @param expectedNextHops Expected next hops; order does not matter.
+   */
+  void
+  checkRoutingTableEntry(const ndn::Name& destination,
+                         std::initializer_list<NextHop> expectedNextHops) const
+  {
+    BOOST_TEST_CONTEXT("Checking routing table entry " << destination)
+    {
+      using NextHopSet = std::set<NextHop, NextHopUriSortedComparator>;
+
+      NextHopSet expectedNextHopSet(expectedNextHops);
+
+      const RoutingTableEntry* entry = routingTable.findRoutingTableEntry(destination);
+      BOOST_REQUIRE(entry != nullptr);
+
+      const NexthopList& actualNextHopList = entry->getNexthopList();
+      NextHopSet actualNextHopSet(actualNextHopList.begin(), actualNextHopList.end());
+
+      BOOST_TEST(expectedNextHopSet == actualNextHopSet, boost::test_tools::per_element());
+    }
   }
 
 public:
@@ -107,7 +162,6 @@
   ConfParameter conf;
   DummyConfFileProcessor confProcessor;
   Nlsr nlsr;
-  NameMap map;
 
   RoutingTable& routingTable;
   Lsdb& lsdb;
@@ -117,180 +171,144 @@
 
 BOOST_AUTO_TEST_CASE(Basic)
 {
-  calculateLinkStateRoutingPath(map, routingTable, conf, lsdb);
-
-  RoutingTableEntry* entryB = routingTable.findRoutingTableEntry(ROUTER_B_NAME);
-  BOOST_REQUIRE(entryB != nullptr);
+  setupRouterA();
+  setupRouterB();
+  setupRouterC();
+  calculatePath();
 
   // Router A should be able to get to B through B and to B through C
-  NexthopList& bHopList = entryB->getNexthopList();
-  BOOST_REQUIRE_EQUAL(bHopList.getNextHops().size(), 2);
-
-  for (const NextHop& hop : bHopList) {
-    auto faceUri = hop.getConnectingFaceUri();
-    uint64_t cost = hop.getRouteCostAsAdjustedInteger();
-
-    BOOST_CHECK((faceUri == ROUTER_B_FACE && cost == LINK_AB_COST) ||
-                (faceUri == ROUTER_C_FACE && cost == LINK_AC_COST + LINK_BC_COST));
-
-  }
-
-  RoutingTableEntry* entryC = routingTable.findRoutingTableEntry(ROUTER_C_NAME);
-  BOOST_REQUIRE(entryC != nullptr);
+  checkRoutingTableEntry(ROUTER_B_NAME, {
+    {ROUTER_B_FACE, LINK_AB_COST},
+    {ROUTER_C_FACE, LINK_AC_COST + LINK_BC_COST},
+  });
 
   // Router A should be able to get to C through C and to C through B
-  NexthopList& cHopList = entryC->getNexthopList();
-  BOOST_REQUIRE_EQUAL(cHopList.getNextHops().size(), 2);
-
-  for (const NextHop& hop : cHopList) {
-    auto faceUri = hop.getConnectingFaceUri();
-    uint64_t cost = hop.getRouteCostAsAdjustedInteger();
-
-    BOOST_CHECK((faceUri == ROUTER_C_FACE && cost == LINK_AC_COST) ||
-                (faceUri == ROUTER_B_FACE && cost == LINK_AB_COST + LINK_BC_COST));
-  }
+  checkRoutingTableEntry(ROUTER_C_NAME, {
+    {ROUTER_C_FACE, LINK_AC_COST},
+    {ROUTER_B_FACE, LINK_AB_COST + LINK_BC_COST},
+  });
 }
 
 BOOST_AUTO_TEST_CASE(Asymmetric)
 {
   // Asymmetric link cost between B and C
-  auto lsa = nlsr.m_lsdb.findLsa<AdjLsa>(ndn::Name(ROUTER_B_NAME));
-  BOOST_REQUIRE(lsa != nullptr);
+  double higherCostBC = LINK_BC_COST + 1;
+  setupRouterA();
+  setupRouterB(higherCostBC);
+  setupRouterC();
 
-  auto c = lsa->m_adl.findAdjacent(ROUTER_C_NAME);
-  BOOST_REQUIRE(c != conf.getAdjacencyList().end());
-
-  double higherLinkCost = LINK_BC_COST + 1;
-  c->setLinkCost(higherLinkCost);
-
-  // Calculation should consider the link between B and C as having cost = higherLinkCost
-  calculateLinkStateRoutingPath(map, routingTable, conf, lsdb);
-
-  RoutingTableEntry* entryB = routingTable.findRoutingTableEntry(ROUTER_B_NAME);
-  BOOST_REQUIRE(entryB != nullptr);
+  // Calculation should consider the link between B and C as having cost = higherCostBC
+  calculatePath();
 
   // Router A should be able to get to B through B and to B through C
-  NexthopList& bHopList = entryB->getNexthopList();
-  BOOST_REQUIRE_EQUAL(bHopList.getNextHops().size(), 2);
-
-  for (const NextHop& hop : bHopList) {
-    auto faceUri = hop.getConnectingFaceUri();
-    uint64_t cost = hop.getRouteCostAsAdjustedInteger();
-
-    BOOST_CHECK((faceUri == ROUTER_B_FACE && cost == LINK_AB_COST) ||
-                (faceUri == ROUTER_C_FACE && cost == LINK_AC_COST + higherLinkCost));
-
-  }
-
-  RoutingTableEntry* entryC = routingTable.findRoutingTableEntry(ROUTER_C_NAME);
-  BOOST_REQUIRE(entryC != nullptr);
+  checkRoutingTableEntry(ROUTER_B_NAME, {
+    {ROUTER_B_FACE, LINK_AB_COST},
+    {ROUTER_C_FACE, LINK_AC_COST + higherCostBC},
+  });
 
   // Router A should be able to get to C through C and to C through B
-  NexthopList& cHopList = entryC->getNexthopList();
-  BOOST_REQUIRE_EQUAL(cHopList.getNextHops().size(), 2);
-
-  for (const NextHop& hop : cHopList) {
-    auto faceUri = hop.getConnectingFaceUri();
-    uint64_t cost = hop.getRouteCostAsAdjustedInteger();
-
-    BOOST_CHECK((faceUri == ROUTER_C_FACE && cost == LINK_AC_COST) ||
-                (faceUri == ROUTER_B_FACE && cost == LINK_AB_COST + higherLinkCost));
-  }
+  checkRoutingTableEntry(ROUTER_C_NAME, {
+    {ROUTER_C_FACE, LINK_AC_COST},
+    {ROUTER_B_FACE, LINK_AB_COST + higherCostBC},
+  });
 }
 
 BOOST_AUTO_TEST_CASE(NonAdjacentCost)
 {
-  // Asymmetric link cost between B and C
-  auto lsa = nlsr.m_lsdb.findLsa<AdjLsa>(ROUTER_B_NAME);
-  BOOST_REQUIRE(lsa != nullptr);
-
-  auto c = lsa->m_adl.findAdjacent(ROUTER_C_NAME);
-  BOOST_REQUIRE(c != conf.getAdjacencyList().end());
-
-  // Break the link between B - C by setting it to a NON_ADJACENT_COST.
-  c->setLinkCost(Adjacent::NON_ADJACENT_COST);
+  // Break the link between B - C by setting it to NON_ADJACENT_COST.
+  setupRouterA();
+  setupRouterB(
+    Adjacent::NON_ADJACENT_COST // B to C
+  );
+  setupRouterC();
 
   // Calculation should consider the link between B and C as down
-  calculateLinkStateRoutingPath(map, routingTable, conf, lsdb);
+  calculatePath();
 
   // Router A should be able to get to B through B but not through C
-  RoutingTableEntry* entryB = routingTable.findRoutingTableEntry(ROUTER_B_NAME);
-  BOOST_REQUIRE(entryB != nullptr);
-
-  auto bHopList = entryB->getNexthopList();
-  BOOST_REQUIRE_EQUAL(bHopList.getNextHops().size(), 1);
-
-  const auto nextHopForB = bHopList.getNextHops().begin();
-
-  BOOST_CHECK(nextHopForB->getConnectingFaceUri() == ROUTER_B_FACE &&
-              nextHopForB->getRouteCostAsAdjustedInteger() == LINK_AB_COST);
+  checkRoutingTableEntry(ROUTER_B_NAME, {
+    {ROUTER_B_FACE, LINK_AB_COST},
+  });
 
   // Router A should be able to get to C through C but not through B
-  auto entryC = routingTable.findRoutingTableEntry(ROUTER_C_NAME);
-  BOOST_REQUIRE(entryC != nullptr);
-
-  NexthopList& cHopList = entryC->getNexthopList();
-  BOOST_REQUIRE_EQUAL(cHopList.getNextHops().size(), 1);
-
-  const auto nextHopForC = cHopList.getNextHops().begin();
-
-  BOOST_CHECK(nextHopForC->getConnectingFaceUri() == ROUTER_C_FACE &&
-              nextHopForC->getRouteCostAsAdjustedInteger() == LINK_AC_COST);
+  checkRoutingTableEntry(ROUTER_C_NAME, {
+    {ROUTER_C_FACE, LINK_AC_COST},
+  });
 }
 
 BOOST_AUTO_TEST_CASE(AsymmetricZeroCostLink)
 {
   // Asymmetric and zero link cost between B - C, and B - A.
-  auto lsaB = nlsr.m_lsdb.findLsa<AdjLsa>(ROUTER_B_NAME);
-  BOOST_REQUIRE(lsaB != nullptr);
+  setupRouterA(
+    0 // A to B
+  );
+  setupRouterB(
+    0, // B to C: effective cost is still LINK_BC_COST, as specified on C-B link
+    0  // B to A
+  );
+  setupRouterC();
 
-  auto c = lsaB->m_adl.findAdjacent(ROUTER_C_NAME);
-  BOOST_REQUIRE(c != conf.getAdjacencyList().end());
-  // Re-adjust link cost to 0 from B-C. However, this should not set B-C cost 0 because C-B
-  // cost is greater that 0 i.e. 17
-  c->setLinkCost(0);
-
-  auto a = lsaB->m_adl.findAdjacent(ROUTER_A_NAME);
-  BOOST_REQUIRE(a != conf.getAdjacencyList().end());
-
-  auto lsaA = nlsr.m_lsdb.findLsa<AdjLsa>(ROUTER_A_NAME);
-  BOOST_REQUIRE(lsaA != nullptr);
-
-  auto b = lsaA->m_adl.findAdjacent(ROUTER_B_NAME);
-  BOOST_REQUIRE(b != conf.getAdjacencyList().end());
-
-  // Re-adjust link cost to 0 from both the direction i.e B-A and A-B
-  a->setLinkCost(0);
-  b->setLinkCost(0);
-
-  // Calculation should consider 0 link-cost between B and C
-  calculateLinkStateRoutingPath(map, routingTable, conf, lsdb);
+  // Calculation should consider 0 link-cost between A and B
+  calculatePath();
 
   // Router A should be able to get to B through B and C
-  RoutingTableEntry* entryB = routingTable.findRoutingTableEntry(ROUTER_B_NAME);
-  BOOST_REQUIRE(entryB != nullptr);
-
-  // Node can have neighbors with zero cost, so the nexthop count should be 2
-  NexthopList& bHopList = entryB->getNexthopList();
-  BOOST_REQUIRE_EQUAL(bHopList.getNextHops().size(), 2);
-
-  const auto nextHopForB = bHopList.getNextHops().begin();
-  // Check if the next hop via B is through A or not after the cost adjustment
-  BOOST_CHECK(nextHopForB->getConnectingFaceUri() == ROUTER_B_FACE &&
-              nextHopForB->getRouteCostAsAdjustedInteger() == 0);
+  checkRoutingTableEntry(ROUTER_B_NAME, {
+    {ROUTER_B_FACE, 0},
+    {ROUTER_C_FACE, LINK_AC_COST + LINK_BC_COST},
+  });
 
   // Router A should be able to get to C through C and B
-  auto entryC = routingTable.findRoutingTableEntry(ROUTER_C_NAME);
-  BOOST_REQUIRE(entryC != nullptr);
+  checkRoutingTableEntry(ROUTER_C_NAME, {
+    {ROUTER_C_FACE, LINK_AC_COST},
+    {ROUTER_B_FACE, 0 + LINK_BC_COST},
+  });
+}
 
-  NexthopList& cHopList = entryC->getNexthopList();
-  BOOST_REQUIRE_EQUAL(cHopList.getNextHops().size(), 2);
+BOOST_AUTO_TEST_CASE(OnePath)
+{
+  double costBC = 2.0;
+  setupRouterA();
+  setupRouterB(
+    costBC // B to C
+  );
+  setupRouterC(
+    LINK_AC_COST, // C to A
+    costBC // C to B
+  );
 
-  const auto nextHopForC = cHopList.getNextHops().begin();
-  // Check if the nextHop from C is via A or not
-  BOOST_CHECK(nextHopForC->getConnectingFaceUri() == ROUTER_C_FACE &&
-              nextHopForC->getRouteCostAsAdjustedInteger() == LINK_AC_COST);
+  // Calculate only one path per destination router.
+  conf.setMaxFacesPerPrefix(1);
+  // This triggers a different code path.
+  calculatePath();
 
+  // Shortest path to router B is via router B.
+  checkRoutingTableEntry(ROUTER_B_NAME, {
+    {ROUTER_B_FACE, LINK_AB_COST},
+  });
+
+  // Shortest path to router C is via router B.
+  checkRoutingTableEntry(ROUTER_C_NAME, {
+    {ROUTER_B_FACE, LINK_AB_COST + costBC},
+  });
+}
+
+BOOST_AUTO_TEST_CASE(SourceRouterAbsent)
+{
+  // RouterA does not exist in the LSDB.
+  // setupRouterA is not invoked.
+  setupRouterB(
+    LINK_BC_COST, // B to C
+    NAN           // B to A: skipped
+  );
+  setupRouterC(
+    NAN // C to A: skipped
+  );
+
+  // Calculation should do nothing and not cause errors.
+  calculatePath();
+
+  // There should be no routes.
+  BOOST_CHECK(routingTable.m_rTable.empty());
 }
 
 BOOST_AUTO_TEST_SUITE_END()
