我正在尝试编写一个单元测试,该测试需要确认是否调用了方法。我正在使用JUnit、Mockito和PowerMock。
公共类发票{protected void createInvoice(){//这里有随机的东西markInvoiceAs已开票("57");}受保护的无效标记InvoiceAs已填充(字符串代码){//标记为已开票}}
所以,这里我的测试系统是Invoice
。我正在运行这个测试:
公共类InvoiceTest{@测试public void testInvoiceMarkedAsBilled(){Invoice sut=新发票();发票sutSpy=间谍(sut);sut.createInvoice();//我想验证是否调用了markInvoiceAs()}}
此示例只是实际代码的一个示例。。。。
我的问题是mockito说你只能验证是否在一个模拟对象上调用了一个方法。。。但我不想嘲笑这个对象,因为它是我正在测试的对象。我知道你可以监视你正在测试的对象,所以下面是我尝试的:
verify(sutSpy).markInvoiceAs已开票("57")
我想做的是不可能的吗?还是我只是走错了路?
谢谢大家:)
我不确定你试图做的事情是否是最好的方式。
我不关心验证Invoice.createInvoice()
是否调用了内部私有方法markInvoiceAsBilled()
,而是测试调用createInvoice()
是否以您期望的方式更改Invoice对象的状态,即status
现在是BILLED
或类似的方法。
换句话说——不要测试createInvoice()
调用了什么方法——测试调用该方法后,对象的状态是您所期望的。
我同意matt-b的回答。也就是说,根据用例和方法的复杂性,您可以重新设计您的单元,以便对其进行测试。
例如,您的对象变得更加复杂,例如
public A {
public a() {
b();
c();
}
public b() { /** hairy code, many branches to test */ }
public c() { /** hairy code, many branches to test */ }
}
用测试覆盖b,用测试覆盖c是直接的,但覆盖a似乎很麻烦,因为你依赖于方法b和c。
相反,考虑这种设计
public A {
private final Dep mDep;
public a() {
mDep.b();
mDep.c();
}
public b() {
mDep.b();
}
public c() {
mDep.c();
}
// dependency abstraction we create to help test
static class Dep {
public b() { /** hairy code, many branches to test */ }
public c() { /** hairy code, many branches to test */ }
}
}
现在,测试A.a
、A.b
和A.c
只需要验证是否调用了mDep
(以及该方法所做的其他操作)。分别测试A.Dep.b
和A.Dep.c
方法。