Clik here to view.

1. Introduction
While Mockito provides an excellent way to avoid initializing objects we don’t want to initialize, sometimes its out-of-the-box functionality is limiting.
In this tutorial, we’ll explore various ways of stubbing setters and getters in the context of a unit test.
2. Mocks vs Actual Objects
Before we write any tests, let’s understand the difference between a stub and a mock. We use the term stub to describe an object that doesn’t provide any flexibility regarding its behavior. On the contrary, mocks allow configurable behavior and provide verification capabilities.
To help us look at examples that somewhat resemble real-world scenarios, the ExampleService class invokes other objects’ methods, stubbed or not:
public class ExampleService {
public <T> T getField(Supplier<T> getter) {
return getter.get();
}
public <T> void setField(Consumer<T> setter, T value) {
setter.accept(value);
}
}
ExampleService is implemented with reusability in mind, hence the argument choice for both getField() and setField() methods. Simply put, the getField() method invokes any Supplier it accepts, so in our case, getter methods. In contrast, the setField() method invokes any Consumer it accepts – in our case setter methods – using the value provided.
For clarity, let’s write some examples of getter and setter invocations using ExampleService:
exampleService.getField(() -> fooBar.getFoo()); // invokes getFoo getter
exampleService.getField(fooBar::getBar); // invokes getFoo getter
exampleService.setField((bar) -> fooBar.setBar(bar), "newBar"); // invokes bar setter
exampleService.setField(fooBar::setBar, "newBar"); // invokes bar setter
The last step before we start writing tests is to define the model that we’ll use, namely SimpleClass:
public class SimpleClass {
private Long id;
private String name;
// getters, setters, constructors
To begin with, mocking an object that is relatively lightweight and easy to initialize is often not optimal. Indeed, the code we’ll need to write to mock an object is more lengthy than just creating an instance of that object. The following snippet contains a mock object with stubbed setters and getters as well as the verifications at the end:
@Test
public void givenMockedSimpleClass_whenInvokingSettersGetters_thenInvokeMockedSettersGetters() {
Long mockId = 12L;
String mockName = "I'm 12";
SimpleClass simpleMock = mock(SimpleClass.class);
when(simpleMock.getId()).thenReturn(mockId);
when(simpleMock.getName()).thenReturn(mockName);
doNothing().when(simpleMock).setId(anyLong());
doNothing().when(simpleMock).setName(anyString());
ExampleService srv = new ExampleService();
srv.setField(simpleMock::setId, 11L);
srv.setField(simpleMock::setName, "I'm 11");
assertEquals(srv.getField(simpleMock::getId), mockId);
assertEquals(srv.getField(simpleMock::getName), mockName);
verify(simpleMock).getId();
verify(simpleMock).getName();
verify(simpleMock).setId(eq(11L));
verify(simpleMock).setName(eq("I'm 11"));
}
To put things into perspective, here’s the same test without mocking:
@Test
public void givenActualSimpleClass_whenInvokingSettersGetters_thenInvokeActualSettersGetters() {
Long id = 1L;
String name = "I'm 1";
SimpleClass simple = new SimpleClass(id, name);
ExampleService srv = new ExampleService();
srv.setField(simple::setId, 2L);
srv.setField(simple::setName, "I'm 2");
assertEquals(srv.getField(simple::getId), simple.getId());
assertEquals(srv.getField(simple::getName), simple.getName());
}
When comparing the two test cases, it becomes apparent that the mock variation is eight lines longer. In general, mock stub setup and verification lead to lengthier test cases.
3. Simple Mocks
The most common case to use Mockito stubbing is when an object creation requires many lines of code or its initialization is slow leading to poor test suite performance. Conveniently, Mockito’s when() and thenReturn() methods provide a way to avoid creating real objects. For this example, we need a more complex object than the SimpleClass, so let’s introduce NonSimpleClass:
public class NonSimpleClass {
private Long id;
private String name;
private String superComplicatedField;
// getters, setters, constructors
As the name implies, superComplicatedField requires special handling. Hence, it’s imperative that we don’t initialize it during our tests:
@Test
public void givenNonSimpleClass_whenInvokingGetName_thenReturnMockedName() {
NonSimpleClass nonSimple = mock(NonSimpleClass.class);
when(nonSimple.getName()).thenReturn("Meredith");
ExampleService srv = new ExampleService();
assertEquals(srv.getField(nonSimple::getName), "Meredith");
verify(nonSimple).getName();
}
In this scenario, creating an instance of NonSimpleClass would lead to performance issues or unnecessary code. On the contrary, Mockito stubbing yields the desired test coverage without introducing any negative effects related to NonSimpleClass instantiation.
4. Stateful Mocks
Mockito doesn’t offer object state management out-of-the-box. In our case, a value set by a setter won’t be returned by the getter’s following invocation unless we do some magic. For this issue, a viable solution is a stateful mock so that when a getter is called after a setter, the getter returns the value that was set last. The Wrapper class, which as the name implies, wraps a value, is responsible for the state management:
class Wrapper<T> {
private T value;
// getter, setter, constructors
To leverage the Wrapper class, instead of the thenReturn() and doNothing() Mockito methods, we use doAnswer() and thenAnswer(). These variants allow us to access the arguments of a mock method and apply custom logic instead of simply returning a static value:
@Test
public void givenNonSimpleClass_whenInvokingGetName_thenReturnTheLatestNameSet() {
Wrapper<String> nameWrapper = new Wrapper<>(String.class);
NonSimpleClass nonSimple = mock(NonSimpleClass.class);
when(nonSimple.getName()).thenAnswer((Answer<String>) invocationOnMock -> nameWrapper.get());
doAnswer(invocation -> {
nameWrapper.set(invocation.getArgument(0));
return null;
}).when(nonSimple)
.setName(anyString());
ExampleService srv = new ExampleService();
srv.setField(nonSimple::setName, "John");
assertEquals(srv.getField(nonSimple::getName), "John");
srv.setField(nonSimple::setName, "Nick");
assertEquals(srv.getField(nonSimple::getName), "Nick");
}
Our stateful mock uses the underlying wrapper instance to keep the latest value set when the setter is invoked and returns the last value set when the mocked getter is called.
5. Conclusion
In this quick article, we went over various mocking scenarios and discussed when it’s convenient to use a mock and when it’s not. Additionally, we showcased a solution for a stateful mock which also demonstrated the versatility of the Mockito library, allowing us to simulate quite complex scenarios if needed.
As always, the source code for this tutorial is available over on GitHub.
The post Stub Getter and Setter in Mockito first appeared on Baeldung.Image may be NSFW.
Clik here to view.