【发布时间】:2011-04-08 20:23:06
【问题描述】:
我正在尝试编写一个单元测试(使用 JMockit)来验证方法是根据部分顺序调用的。具体的用例是确保在事务中调用某些操作,但更一般地说,我想验证这样的事情:
- 方法
beginTransaction被调用。 - 方法
operation1到operationN以任意顺序调用。 - 方法
endTransaction被调用。 - 方法
someOtherOperation在事务之前、期间或之后的某个时间被调用。
Expectations 和 Verifications API 似乎无法处理此要求。
如果我有 @Mocked BusinessObject bo,我可以验证是否调用了正确的方法(以任何顺序):
new Verifications() {{
bo.beginTransaction();
bo.endTransaction();
bo.operation1();
bo.operation2();
bo.someOtherOperation();
}};
可选择将其设为FullVerifications 以检查是否没有其他副作用。
要检查排序约束,我可以这样做:
new VerificationsInOrder() {{
bo.beginTransaction();
unverifiedInvocations();
bo.endTransaction();
}};
但这不能处理someOtherOperation 的情况。我不能用bo.operation1(); bo.operation2() 替换unverifiedInvocations,因为这会对调用进行total 排序。业务方法的正确实现可以调用bo.operation2(); bo.operation1()。
如果我成功了:
new VerificationsInOrder() {{
unverifiedInvocations();
bo.beginTransaction();
unverifiedInvocations();
bo.endTransaction();
unverifiedInvocations();
}};
然后,当在事务之前调用 someOtherOperation 时,我会收到“没有未验证的调用”失败。尝试bo.someOtherOperation(); minTimes = 0 也不起作用。
那么:有没有一种简洁的方法来使用 JMockIt 中的 Expectations/Verifications API 指定方法调用的部分排序要求?还是我必须使用MockClass 并手动跟踪调用,a la:
@MockClass(realClass = BusinessObject.class)
public class MockBO {
private boolean op1Called = false;
private boolean op2Called = false;
private boolean beginCalled = false;
@Mock(invocations = 1)
public void operation1() {
op1Called = true;
}
@Mock(invocations = 1)
public void operation2() {
op2Called = true;
}
@Mock(invocations = 1)
public void someOtherOperation() {}
@Mock(invocations = 1)
public void beginTransaction() {
assertFalse(op1Called);
assertFalse(op2Called);
beginCalled = true;
}
@Mock(invocations = 1)
public void endTransaction() {
assertTrue(beginCalled);
assertTrue(op1Called);
assertTrue(op2Called);
}
}
【问题讨论】:
-
Verifications API 支持有多个验证块,这将是这里的解决方案:
someOtherOperation应在常规块中验证在包含调用的有序验证块中unverifiedInvocations()。但是,JMockit 目前不支持这种特定组合。我将尝试在 0.999.9 版本中修复它。 -
但这真的支持偏序场景吗?要求 bo.operation1() 和 bo.operation2() 必须都发生在 bo.beginTransaction() 之后和 bo.endTransaction() 之前,但是在事务中这两个操作可以以任何顺序发生。这正是我还需要测试的场景。
标签: java unit-testing mocking jmockit