问题
I'm trying to write a unit test that needs to confirm if a method is called or not. I'm using JUnit, Mockito and PowerMock.
public class Invoice { protected void createInvoice() { // random stuff here markInvoiceAsBilled("57"); } protected void markInvoiceAsBilled(String code) { // marked as billed } }
So, here my system under test is Invoice
. I'm running this test:
public class InvoiceTest { @Test public void testInvoiceMarkedAsBilled() { Invoice sut = new Invoice(); Invoice sutSpy = spy(sut); sut.createInvoice(); // I want to verify that markInvoiceAsBilled() was called } }
This example is just an example of what the actual code looks like....
My problem is that mockito says you can only verify if a method is called on a mocked object... but I don't want to mock this object, as it's my object under test. I know that you can spy on the object you're testing, so here's what I tried:
verify(sutSpy).markInvoiceAsBilled("57");
Is what I'm trying to do not possible? Or am I just going about it the wrong way?
Thanks everyone :)
回答1:
I'm not sure if what you are attempting to do is the best way to go about things.
I wouldn't concern myself with verifying that Invoice.createInvoice()
calls an internal, private method markInvoiceAsBilled()
- instead test that calling createInvoice()
changes the state of the Invoice object in the way you expect - i.e., that status
is now BILLED
or something similar.
In other words - don't test what methods are called by createInvoice()
- test that after calling this method, the state of the object is what you expect.
回答2:
I agree with matt-b's answer. That being said, depending on the use case and the complexity of the method, you can redesign your unit so that it can be tested.
Say for example your object gets much more complicated, e.g.
public A {
public a() {
b();
c();
}
public b() { /** hairy code, many branches to test */ }
public c() { /** hairy code, many branches to test */ }
}
Covering b with tests and c with tests is straight-forward, but covering a would seem like a hassle since you depend on methods b and c.
Consider instead this design
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 */ }
}
}
Now, testing A.a
, A.b
and A.c
just requires you to verify your mDep
is called (among whatever else the method does). Separately, you test A.Dep.b
and A.Dep.c
methods.
来源:https://stackoverflow.com/questions/12429157/how-to-verify-if-method-is-called-on-system-under-test-not-a-mock