Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Mockito模拟ResultSet.next()方法_Java_Unit Testing_Mockito - Fatal编程技术网

Java 如何使用Mockito模拟ResultSet.next()方法

Java 如何使用Mockito模拟ResultSet.next()方法,java,unit-testing,mockito,Java,Unit Testing,Mockito,我像这样模仿java.sql.ResultSet ResultSet rs = mock(ResultSet.class); when(rs.next()).thenReturn(true); // this seems wrong appraoch while (rs.next()) { // doing stuff here } 测试代码是这样的 ResultSet rs = mock(ResultSet.class); when(rs.next()).thenReturn(true

我像这样模仿
java.sql.ResultSet

ResultSet rs = mock(ResultSet.class);
when(rs.next()).thenReturn(true); // this seems wrong appraoch
while (rs.next()) {
  // doing stuff here
}
测试代码是这样的

ResultSet rs = mock(ResultSet.class);
when(rs.next()).thenReturn(true); // this seems wrong appraoch
while (rs.next()) {
  // doing stuff here
}
所以问题是,当我将mock
rs.next()
设置为
true
时,然后将
设置为while
循环从不终止。我想在2次迭代后终止
,而
循环。那么如何模拟
rs.next()
方法呢

我也试过了

when(rs.next()).thenReturn(true, true, false); // always return false 

请帮忙

您可以链接
doReturn()
方法调用:

doReturn(true).doReturn(true).doReturn(false).when(rs).next();
when(rs.next()).thenReturn(true).thenReturn(true).thenReturn(false);
或者,如注释中所述,chain
然后return
方法调用:

doReturn(true).doReturn(true).doReturn(false).when(rs).next();
when(rs.next()).thenReturn(true).thenReturn(true).thenReturn(false);
或者,如果您想更进一步,可以使用Mockito
Answer
s:

when(rs.next()).thenAnswer(new Answer() {
    private int iterations = 2;

    Object answer(InvocationOnMock invocation) {
        return iterations-- > 0;
    }
});
试一试


虽然其他答案在技术上是正确的(如果在代码中不起作用,那么可能还有其他原因,需要更多的代码)。他们都忽略了一个关键点:

您不应该模拟JDBC类,而应该创建一个带有真实数据库的集成测试。还要注意,
ResultSet
确实是一个接口,但是drivers/DB在行为上可能有一些差异。这样的测试模仿了这些,使开发人员对真实的生产行为视而不见

如果这段代码只是处理返回的数据,而不是实际的JDBC调用代码,那么这段代码应该与JDBC类解耦,因为不应该导入
ResultSet
。从长远来看,它有助于从业务代码中分离技术代码

when(rs.next()).thenReturn(true, true, false);
这应该行得通

我从javadoc中找到了一个例子“mockitocore:1.10.19”

看看这个:

您还可以链接thenReturn:when(rs.next()).thenReturn(true)。thenReturn(false)这两种方法的行为与:when(rs.next()).thenReturn(true,true,false)相同;这不是工作情况:(它总是将最后一个值作为结果,然后返回?刚刚使用Mockito 1.10.19在本地进行了测试。我的代码工作正常。好的,你的代码在技术上对我来说也很好,但我告诉了一些人我怎么可能遗漏了什么,并且无法理解:(我每次在rs上都会出错。next():(Mockito 2.0.2 beta版不适用于我。如果你仍然被卡住,也许你应该编辑你的问题,用你尝试的修复添加完整的测试,并提及Mockito的版本,以防有人知道某个bug。我在另一个测试中使用了你的方法,它可以正常工作,但在这个特定的场景中不会。我想我是missi不知道是什么(嗯,我想你是对的。我使用了mockrunner lib的MockResultSet。它工作得很好,但我不能用它做其他主要的事情。我并不反对集成测试的需要,但说你只需要像这样的情况下进行集成测试是一个太远的桥梁。完全有可能较低级别的DAO类型代码是需要的如果返回不同数量的结果,则具有不同的属性(例如,如果返回多个记录,则引发异常)。使用单元测试测试这种行为是完全有意义的。@RobbyCornelissen是的,当然总有一些很好的理由不遵循这些指导原则,但这通常是非常狭隘的情况;这里似乎不是这样。无论如何,即使对于您提到的情况,实现者或不同版本也可能会以不同的方式失败,并出现意外的情况ys,取决于适当的条件。测试这些条件可能会被证明是非常具有挑战性的,在这里使用DB进行额外的模拟可能会给人一种错误的安全感。外部系统要正确、安全地进行测试比我们过去认为的要困难得多,而且模拟很少(如果是其中的一部分)。