Mockito Programming Model: Difference between revisions
Line 79: | Line 79: | ||
The <code>when()</code> configures the method(s) to stub, or the '''trigger action'''. The <code>then*()</code> methods specify what to do when the trigger is activated. Void methods are a [[#Void_Methods|special case]]. | The <code>when()</code> configures the method(s) to stub, or the '''trigger action'''. The <code>then*()</code> methods specify what to do when the trigger is activated. Void methods are a [[#Void_Methods|special case]]. | ||
==Void Methods== | ==Void Methods== | ||
By default, the managed test double does nothing on void methods, so there's no need to configure anything on it. The void method invoked on it will just work. | By default, the managed test double does nothing on void methods, so there's no need to configure anything on it. The void method invoked on it will just work. If we need to simulate an exception that is thrown by a void method, use this pattern: | ||
==Stub Responses== | ==Stub Responses== | ||
===<tt>thenReturn()</tt>=== | ===<tt>thenReturn()</tt>=== |
Revision as of 17:48, 16 July 2021
Internal
Overview
API
import static org.mockito.Mockito.mock;
import com.example.ExternalDependency;
public class SomeClassTest {
private ExternalDependency mockExternalDependency;
@Before
public void setUp() {
mockExternalDependency = mock(ExternalDependency.class);
}
@Test
public void someTest() throws Exception {
...
}
}
Annotations
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import com.example.ExternalDependency;
public class SomeClassTest {
private AutoCloseable mocks;
@Mock
private ExternalDependency mockExternalDependency;
@Before
public void openMocks() {
mocks = MockitoAnnotations.openMocks(this);
}
@After
public void releaseMocks() throws Exception {
mocks.close();
}
@Test
public void someTest() throws Exception {
...
}
}
Implementing Stub Functionality
A stub returns synthetic responses or throws exceptions when its methods are invoked. Mockito supports stubbing and by returning a given value when a specific method of the managed test double is called. Mockito implements the stub functionality with Mockito.when(<method>).thenReturn(...)
pattern:
public class ExternalDependency {
public String someMethod() {
...
}
}
public class SomeClassTest {
@Mock
private ExternalDependency mockExternalDependency;
@Test
public void someTest() throws Exception {
Mockito.when(mockExternalDependency.someMethod()).thenReturn("some synthetic result");
...
}
}
The when()
configures the method(s) to stub, or the trigger action. The then*()
methods specify what to do when the trigger is activated. Void methods are a special case.
Void Methods
By default, the managed test double does nothing on void methods, so there's no need to configure anything on it. The void method invoked on it will just work. If we need to simulate an exception that is thrown by a void method, use this pattern:
Stub Responses
thenReturn()
thenReturn(...)
returns the given value. It has several variants:
thenReturn(value)
: return the same value every time.thenReturn(value1, value2, value3, ...)
: return the first value on first invocation, second value on the second invocation, etc. The equivalent is:thenReturn(value1).thenReturn(value2).thenReturn(value3). ...
thenThrow()
thenThrow(Throwable)
throws the given exception. This can be used together with JUnit feature that provides syntactic support for tests that are supposed to check exceptions (@Test(expected = <exception-class>)
).
when(mockExternalDependency.someMethod()).thenThrow(IOException.class);
Alternative syntax for throwing exceptions on methods that return void
Why is this necessary? Why can't we use the normal thenThrow()?
doThrow(exception).when(mock).<voidmethod>(arguments);
thenAnswer()
thenAnswer(Answer answer)
executes custom logic and compute a value to return. This turns the stub object into a fake.
thenCallRealMethod()
thenCallRealMethod()
delegates the invocation to the real external dependency.
Argument Matchers
isA()
public class ExternalDependency {
public String someMethodWithArg(String s) {
...
}
}
import static org.mockito.ArgumentMatchers.isA;
...
Mockito.when(mockExternalDependency.someMethodWithArg(isA(String.class))).thenReturn(...);
}
Why is isA() needed, why not provide the class, directly?