Instantiating mocks
- We can use MockitoJUnitRunner or MockitoRule.
- Prefer using MockitoRule as we can use another runner or when test class extends another base class which uses another runner.
@RunWith(JUnit4.class)
public class ClassUnderTest {
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private Dependence d1;
private ClassUnderTest cut;
@Before
public void setup() {
cut = new ClassUnderTest(d1);
}
}
Create Mock and Stub
- Mockito creates dummies which returns “smart zeros” when called, i.e. empty list, zero, false or, as a last resort, null.
- Create a stub for the relevant methods to return a specific value
Mockito.when(someObject.someMethod()).thenReturn(someValue)
- we can return different values based on the number of calls to the method, or by examining the input parameters (with parameter matchers).
// always return same value
when(someObject.someMethod()).thenReturn(someValue);
when(someObject.someMethod()).thenReturn(firstValue).thenReturn(secondValue);
// shorter form
when(someObject.someMethod()).thenReturn(firstValue, secondValue)
// Throw exception if called more then once
when(someObject.someMethod()).thenReturn(firstValue).thenThrow(new AssertionError("Should only be called one"));
// for void method
doThrow(new SomeException()).when(someObject).someMethod();
Mock chained calls
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
SomeService service;
when(service.getX().getY()).thenReturn(Z);
Spy
- used to wrap a real object. Every call, unless specified otherwise, is delegated to the object;
- we can mock or verify some methods.
- Prefer use a real object instead of spy
doReturn|Answer|Throw()
- Important gotcha on spying real objects!
- use doReturn|Answer|Throw() to stub spy object
- use doXXX on void methods
// spy instance field
Typex ox = Mockito.spy(anObject.aField);
anObject.aField = ox;
doReturn("some").when(spyObj).someMethod();
doCallRealMethod().when(instance).voidMethod();
doThrow(new Exception()).when(instance).voidMethod()
Argument Matcher
- Only used with when() and verify() methods
- org.mockito.ArgumentMatchers
- any(someObject.class), anyString(), anyInt()
- eq: If you are using argument matchers, all arguments have to be provided by matchers.
verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));
//above is correct - eq() is also an argument matcher
verify(mock).someMethod(anyInt(), anyString(), "third argument");
//above is incorrect - exception will be thrown because third argument is given without argument matcher.
- org.mockito.AdditionalMatchers: gt, lt, and, or, not…
Verify
- Verify the expect method(s) are called with the expected value(s) on the given mock(s)
Mockito.verify(someObject).someMethod()
- only verify if calling that exact method matters.
- The default is times(1); exactly once.
- never(), times(n) exactly n times, atLeast(n), atMost(n)
- Verifying the order of calls: InOrder()
- InOrder() ensures the listed calls occur in the order specified. Other calls can occur in any order
- Only use verifyZeroInteractions(), verifyNoMoreInteractions() when needed.
- verifyZeroInteractions(mock) ensures the test never talked to that mock.
- verifyNoMoreInteractions(mock) ensures that there have been no calls to the mock (of any method) that have not been verified
Verify with ArgumentCaptor
- capture arguments that are passed into mocked methods and write assertions against them.
- If the method was called multiple times:
- ArgumentCaptor.getValue() returns the latest captured value
- getAllValues() return all values in order.
Don’t use @InjectMocks or initMocks(this)
- creating a constructor to make the dependencies visible.
###s# Prefer type-safe matchers, expectation setters, and verifiers. - The type-safe approaches can catch type mismatch at compiler time (if we refactor code and change the type later.)
// this is type-safe
when(myObject.myMethod()).thenReturn(someValue);
// this is not type-safe:
doReturn(someValue).when(myObject).myMethod();
Mock Best Practices
- Follow Arrange Act Assert (AAA) when Write Test
- Tests functionality, not implementation
- Prefer testing state over testing interactions
- Don’t Replace Asserts with Verify
- Prefer real objects over fake/mock objects
- Prefer fake objects over mock objects
- Don’t Overuse Mocks