在集成测试中,异步流程(方法,外部服务)构成了非常严格的测试代码。如果相反,我将异步部分考虑在内并创建一个依赖项,并为了测试而将其替换为同步,这是一件“好事”吗?
通过用同步过程替换异步过程,我是不是在集成测试的精神下进行测试?我想我假设集成测试指的是接近真实的测试。
答案 0 :(得分:7)
好问题。
在单元测试中,这种方法是有意义的,但对于集成测试,您应该测试真实系统,因为它将在现实生活中运行。这包括任何异步操作及其可能产生的任何副作用 - 这是存在错误的最可能的地方,可能是您应该集中测试而不是将其排除在外的地方。
我经常使用“waitFor”方法进行轮询以查看是否已收到答案,如果没有,则会暂停一段时间。这种模式的一个很好的实现,虽然特定于Java,你可以获得要点,是JUnitConditionRunner。例如:
conditionRunner = new JUnitConditionRunner(browser, WAIT_FOR_INTERVAL, WAIT_FOR_TIMEOUT);
protected void waitForText(String text) {
try {
conditionRunner.waitFor(new Text(text));
} catch(Throwable t) {
throw new AssertionFailedError("Expecting text " + text + " failed to become true. Complete text [" + browser.getBodyText() + "]");
}
}
答案 1 :(得分:2)
我们有许多自动单元测试可以发送异步请求并需要测试输出/结果。我们处理它的方式是实际执行所有测试,就好像它是实际应用程序的一部分,换句话说,异步请求保持异步。但是测试工具同步起作用:它发送异步请求,睡眠[最多]一段时间(我们期望产生结果的最大值),如果仍然没有结果可用,那么测试失败了。有回调,所以在几乎所有情况下,测试都被唤醒并在超时到期之前继续运行,但是超时意味着失败(或预期性能的变化)不会停止/停止整个测试套件。
这有一些优点:
最后一点可能需要少量解释。性能测试很重要,通常不在测试计划之内。运行这些单元测试的方式,与我们重新安排代码以同步执行所有操作相比,最终会花费更长的时间(运行时间)。但是这样,性能会被隐式测试,并且测试更忠实于它们在应用程序中的使用。此外,我们所有的消息排队基础设施都在此过程中“免费”进行测试。
编辑:添加了有关回调的说明
答案 2 :(得分:0)
你在测试什么?你的班级对某些刺激的反应?在哪种情况下,不合适的模拟工作?
Class Orchestrator implements AsynchCallback {
TheAsycnhService myDelegate; // initialised by injection
public void doSomething(Request aRequest){
myDelegate.doTheWork(aRequest, this)
}
public void tellMeTheResult(Response aResponse) {
// process response
}
}
您的测试可以执行类似
的操作 Orchestrator orch = new Orchestrator(mockAsynchService);
orch.doSomething(request);
// assertions here that the mockAsychService received the expected request
// now either the mock really does call back
// or (probably more easily) make explicit call to the tellMeTheResult() method
// assertions here that the Orchestrator did the right thing with the response
请注意,这里没有真正的异步处理,并且除了允许验证正确请求的接收之外,模拟本身不需要逻辑。对于Orchestrator的单元测试,这就足够了。
在WebSphere Process Server中测试BPEL流程时,我使用了this变体。