1

我正在为一个类似于数据库查询的方法编写一些简单的单元测试:它返回一个可以使用限制(最多 n 个结果)和一个页面(第 p 个 n 个结果集)自定义的结果列表. 我想测试几个案例,例如:

  • 返回所有结果
  • 返回有限结果集的第一页
  • 返回有限结果集的任意页面
  • 返回超出结果总数的有限结果集的最后一页
  • 返回超出结果总数的页面

我需要模拟返回的结果(实际上是名称),所以我只是用一个计数器生成它们,以便根据需要列出“名称 #1”、“名称 #2”等。每个测试看起来(大致)如下:

public void testGetMockCandidatesLimited() throws Exception {
    int numResults = 4;
    setupMock(numResults);
    results = queryFunction(...);

    // Check that the expected number of results was returned
    assertEquals(numResults, results.size());
    // Check that the results are correct and in order
    for (int i = 0; i < numResults; i++) {
        assertEquals(result.get(i).getName(), "Name #" + (i + 1));
    }
}

我的问题是:以这种方式“生成”预期答案可以吗?这是一个微不足道的例子,但下一步是编写一个测试来编写一个测试以分别获得两个结果的第二页,我有:

    final int TEST_LIMIT = 2, TEST_PAGE = 1;
    // Check that the expected number of results was returned
    assertEquals(numResults, results.size());
    // Check that the results are correct and in order
    for (int i = TEST_LIMIT * TEST_PAGE; i < TEST_LIMIT * TEST_PAGE + TEST_LIMIT; i++) {
        assertEquals(result.get(i).getName(), "Name #" + (i + 1));
    }

现在碰巧这个测试是“正确的”,因为我将采用我期望的值并确保结果是“Name #3”和“Name #4”。但是,我的 queryFunction 也会以相同的方式(limit * page + limit某种事物)计算返回的结果。

这是令人担忧的,因为如果测试以与被测单元相同的方式生成预期答案,则它不会检测该方法中是否存在错误。然而,用常量命名输入值使得测试比仅仅在任何地方插入 1 到 4 之间的魔法整数更具可读性。

对于可读性和可维护性(例如,将来是否需要更改值),处理这种情况的最佳方法是什么?

4

1 回答 1

1

在问这个问题时,我想我已经说服自己,解决方案是将预期值也定义为预先的常量,例如:

final int LIMIT = 2, PAGE = 1, MIN_RESULT = 3, MAX_RESULT = 4;

...然后在断言中使用这些值。这保留了命名键值的所有可读性,并阻止了生成预期输出的诱惑。在这种情况下,我仍然会使用循环来生成Name #MINand之间的每个预期名称Name #MAX,但边界本身将是显式静态的。

这是尽可能好,还是有更好的方法来处理这种重复性?

于 2013-03-07T01:54:24.333 回答