问题
I have a program Foo that runs on a device and first calls method1() and then method2() on an external module Bar. When both are called, then in response, Bar calls request() on Foo. To mock Bar, it has a reference to Foo and a method call_Request() which calls foo.request()
// in class BarTest
@Test
public void barFlow() {
InOrder inOrder = inOrder(mockBar);
inOrder.verify(mockBar).method1(anyInt());
inOrder.verify(mockBar).method2();
// what to put as 'thenCallMethod'?
when(mockBar.method2()).thenCallMethod().call_Request();
}
...
// in class Bar
public void call_Request() {
foo.request();
}
I cannot simply put a call to call_Request() in method2 because only when both methods are called in order does the response happen. Other times, different responses may happen.
what Mockito trick will do 'thenCallMethod'?
(I am using the Mockito ver 1.10.19 bundled with Android Studio 2.1)
回答1:
You seem to have no clear definition of what your unit under test is. There seem to be 3 possiblities:
- there are separate tests for
FooandBarand the unit under test is an instance ofFoousing a mock ofBarand an instance ofBarusing a mock ofFoo - the unit under test is an instance of
Foousing a real instance ofBar, but theBarinstance uses aFoomock - the unit under test is an instance of
Foousing a real instance ofBarwhich in turn uses the existing instance ofFoo
In case 1. you could test the following for Bar:
@Test
public void testBar1() {
Foo mockFoo = Mockito.mock(Foo.class);
Bar bar = //obtain unit under test that uses mockFoo
bar.method1(1/*or whatever int value is appropriate*/);
bar.method2();
Mockito.verify(mockFoo).request();
}
@Test
public void testBar1() {
Foo mockFoo = Mockito.mock(Foo.class);
Bar bar = //obtain unit under test that uses mockFoo
bar.method2();
bar.method1(1/*or whatever int value is appropriate*/);
Mockito.verify(mockFoo, Mockito.never()).request();
}
And the test for Foo would look like:
Bar mockBar = Mockito.mock(Bar.class);
Foo foo = //obtain unit under test that uses mockBar
// invoke method on foo that would trigger calls to mockBar
InOrder inOrder = inOrder(mockBar);
inOrder.verify(mockBar).method1(anyInt());
inOrder.verify(mockBar).method2();
In case 2. you would basically repeat the test for Foo from case 1. But you would just verify that Foo.request() was invoked on the mock of Foo used by the instance of Bar. The order of invocations on the Bar instance are not of any interest for this test case.
In case 3. you wouldn't be able to verify any invocations, because there are no mocks used at all.
Using something like
when(mockBar.method2()).thenCallMethod().call_Request();
doesn't make much sense, because you give a mock an implementation, that it might not have in production code.
来源:https://stackoverflow.com/questions/37847774/how-does-one-verify-state-for-a-mock-object