【发布时间】:2015-04-18 23:12:29
【问题描述】:
我有一个类,我想使用 mockito 进行测试。描述类的最好方法是粘贴代码,但我会尽量简短地做到最好。
该类有一个 void 函数并调用另一个通过 setter 和 getter 方法传入的对象。正在调用的对象(来自 void 函数)是异步调用。
我面临的问题是模拟 void 函数(通过 junit 测试)使用的异步调用。
public class Tester {
private Auth auth; // not mock'ed or spy'ed
@Mock private Http transport;
@Before
....
@Test
public void testVoidFunctionFromAuth() {
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return doOutput();
}
}).when(transport).executeAsync(param1, param2, param3...);
auth.obtainAuth(); // void function that uses transport mock class
// obtainAuth calls transport.executeAsync()
// as part of the code
}
// return type of transport.executeAsync() is
// ListenableFuture<ResponseEntity<String>>
private ListenableFuture<ResponseEntity<String>> doOutput() {
return new SimpleAsyncTaskExecutor()
.submitListenable(new Callable<ResponseEntity<String>>() {
@Override
public ResponseEntity<String> call() throws Exception {
....
return responseEntity
}
});
}
}
发生的情况是doOutput() 函数在auth.obtainAuth(); 之前被调用,当obtainAuth() 尝试调用doOutput() 时它返回null——很可能是因为doOutput之前已经在线执行了。我不确定如何在调用 executeAsync 时绑定/注入模拟类(传输)。
【问题讨论】:
-
一般来说,只要让 mock 对象立即返回一个值,如果需要的话,包装在 future 中。
-
@chrylis ya,这通常可以工作,但我们希望模拟对象
Auth实际上不被使用(发出 http 请求)。超出测试范围。 -
这就是你使用模拟的原因;您实际上并没有输入发出请求的对象。听起来您可能并不完全清楚什么是模拟对象。
标签: java spring asynchronous junit mockito