Unit testing 具有生成输入和预期输出的单元测试

Unit testing 具有生成输入和预期输出的单元测试,unit-testing,testing,Unit Testing,Testing,我正在为一个类似于数据库查询的方法编写一些简单的单元测试:它返回一个结果列表,可以使用一个限制(最多n个结果)和一个页面(第p组n个结果)进行定制。我想测试几个案例,例如: final int LIMIT = 2, PAGE = 1, MIN_RESULT = 3, MAX_RESULT = 4; 返回所有结果 返回有限结果集的第一页 返回有限结果集的aribtrary页面 返回超出结果总数的有限结果集的最后一页 返回超出结果总数的页面 我需要模拟返回的结果(实际上是名称),所以我只是用一

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

final int LIMIT = 2, PAGE = 1, MIN_RESULT = 3, MAX_RESULT = 4;
  • 返回所有结果
  • 返回有限结果集的第一页
  • 返回有限结果集的aribtrary页面
  • 返回超出结果总数的有限结果集的最后一页
  • 返回超出结果总数的页面
我需要模拟返回的结果(实际上是名称),所以我只是用一个计数器来生成它们,以便为我所需要的多个结果创建一个“名称1”、“名称2”等列表。每个测试看起来(大致)像:

public void testGetMockCandidatesLimited()引发异常{
int numResults=4;
setupMock(numResults);
结果=查询函数(…);
//检查是否返回了预期数量的结果
assertEquals(numResults,results.size());
//检查结果是否正确且有序
对于(int i=0;i
我的问题是:以这种方式“生成”预期答案可以吗?这是一个简单的示例,但下一步是编写一个测试来编写一个测试,以获得第二页各两个结果,我有:

    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));
    }
final int TEST\u LIMIT=2,TEST\u PAGE=1;
//检查是否返回了预期数量的结果
assertEquals(numResults,results.size());
//检查结果是否正确且有序
对于(int i=测试极限*测试极限页;i<测试极限*测试极限页+测试极限页;i++){
assertEquals(result.get(i).getName(),“Name#”+(i+1));
}
现在正好这个测试是“正确的”,即我将采用我期望的值,并确保结果是“Name#3”和“Name#4”。然而,我的queryFunction也会以同样的方式计算返回哪些结果(
limit*page+limit
之类的东西)

这是令人担忧的,因为如果测试以与被测试单元相同的方式生成预期答案,那么它将无法检测该方法中是否存在错误。但是,使用常量命名输入值比在任何地方插入1到4之间的魔术整数更容易阅读


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

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

final int LIMIT = 2, PAGE = 1, MIN_RESULT = 3, MAX_RESULT = 4;
。。。然后在断言中使用这些值。这将保留命名键值的所有可读性,并阻止生成预期输出的诱惑。在这种情况下,我仍然会使用循环来生成
name#MIN
name#MAX
之间的每个预期名称,但是边界本身是显式静态的


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

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

final int LIMIT = 2, PAGE = 1, MIN_RESULT = 3, MAX_RESULT = 4;
。。。然后在断言中使用这些值。这将保留命名键值的所有可读性,并阻止生成预期输出的诱惑。在这种情况下,我仍然会使用循环来生成
name#MIN
name#MAX
之间的每个预期名称,但是边界本身是显式静态的

这是最好的,还是有更好的方法来处理这种重复性