问题
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
Foo
andBar
and the unit under test is an instance ofFoo
using a mock ofBar
and an instance ofBar
using a mock ofFoo
- the unit under test is an instance of
Foo
using a real instance ofBar
, but theBar
instance uses aFoo
mock - the unit under test is an instance of
Foo
using a real instance ofBar
which 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