我有一个我想用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()
函数在<{em> auth.obtainAuth();
之前被称为,当obtainAuth()
尝试调用doOutput()
时,它会返回{{1> - 很可能是因为null
之前就已经执行过了。我不确定如何在调用doOutput
上绑定/注入模拟类(传输)。
答案 0 :(得分:0)
我不确定我是否理解了这个问题,但是当chrylis
指出时,模拟对象会立即返回一个值。
单元测试应该有自己的上下文,而不依赖于外部资源,因此测试异步调用本身没有意义。它应该返回不同的值,以便您能够测试使用它的类的行为。
要更好地理解模拟定义,请查看以下文章:What is Mocking?
使用Web Flow从Pro Spring MVC引用,单元测试应该
•快跑:单元测试必须运行得非常快。如果它需要等待 对于数据库 连接或外部服务器进程,或解析大文件,它 有用性很快就会变得有限。测试应提供 立即反应和即时满足。
•零外部配置:单元测试不得要求任何外部配置 外部配置文件,甚至不是简单的文本文件。测试的 配置必须由测试框架本身提供和设置 通过调用代码。目的是最小化运行时间 测试并消除外部依赖(可以改变 时间,与测试不同步)。测试用例条件应该 在测试框架中表达,创建更可读的测试 条件。
•独立于其他测试运行:单元测试必须能够运行 完全隔离。换句话说,单元测试不能依赖于某些 其他测试在其自身之前或之后运行。每个测试都是独立的 单元。实际上,测试中的每个测试方法都应该是独立的 并且不依赖于另一种方法或者在a中运行的测试方法 一定的顺序。 •取决于零外部资源:必须进行单元测试 不依赖于任何外部资源,例如数据库连接或 网页服务。这些资源不仅会减慢测试速度,而且会减慢测试速度 它们不受测试控制,因此无法保证 处于正确的测试状态。
•保持外部状态不变:单元测试不得留下任何内容 它曾经跑过的证据。单元测试被编写为可重复的,所以 他们必须自己清理干净。显然,这更容易 当测试不依赖外部资源时(通常是这样) 更难清理或恢复。)
•测试最小的代码单元:单元测试必须测试 可能的最小代码单元,以隔离下的代码 测试。在面向对象的编程中,这个单元通常是一种方法 一个对象或类。编写单元测试以测试方法 独立于其他方法减少了代码行的数量 可能包含潜在的错误。