Mockito Stub Getter & Setter Example
Mockito offers a straightforward approach to mocking method calls in unit tests, helping us isolate components and validate their behavior with ease. While mocking getter methods is usually simple, handling setter methods that influence internal state can be more complex. This article explores effective techniques for stubbing both getters and setters in Mockito.
1. Basic User
Class with Getter and Setter
Before we proceed with mocking techniques, let’s define a simple User
class. This class has a private field username
with standard getter and setter methods.
public class UserService { private User user; public UserService() { } public UserService(User user) { this.user = user; } public String greetUser() { return "Hello, " + user.getUsername(); } public void changeUsername(String newName) { user.setUsername(newName); } }
This User
class serves as a plain data holder with encapsulated access to the username
field. It will be the class we mock in our tests.
UserService
Class That Uses the User
Next, let’s introduce a UserService
class that uses the User
object to greet a user and update their username.
public class UserService { private User user; public UserService(User user) { this.user = user; } public String greetUser() { return "Hello, " + user.getUsername(); } public void changeUsername(String newName) { user.setUsername(newName); } }
The UserService
depends on a User
object. It greets the user using getUsername()
and allows updating the username using setUsername()
.
2. Stubbing a Getter Using when().thenReturn()
Mockito’s when().thenReturn()
construct enables us to define the return value of a method call on a mock object, making it easier to test component interactions in a controlled and deterministic environment. One of the most straightforward applications of this approach is stubbing a getter method. In the example below, a mock User
object is created, and the expected return value of its getUsername()
method is specified.
public class UserTest { @Test void testStubGetter() { User mockUser = mock(User.class); when(mockUser.getUsername()).thenReturn("thomas_pink"); String name = mockUser.getUsername(); assertEquals("thomas_pink", name); // Verify that the getter was called verify(mockUser).getUsername(); } }
In this test, we create a mock of User
, then use when().thenReturn()
to define the behavior of getUsername()
. The method returns “thomas_pink”, as expected, and we verify that the getter was indeed called. This is a basic example of mocking a getter.
3. Stubbing Getter and Setter with Simulated State
When both getter and setter methods need to be mocked, especially when simulating state changes, it’s important to replicate the behavior of storing and retrieving values. Since setters in Java return void
, they cannot be stubbed using when().thenReturn()
like getters. Instead, Mockito’s doAnswer()
can be used to capture and store the input, while thenAnswer()
can simulate returning the stored value when the getter is invoked.
public class UserServiceTest { @Test void testChangeUsernameAndGreetUser() { // Mock the User class User mockedUser = Mockito.mock(User.class); // Use AtomicReference to simulate internal state AtomicReference<String> usernameRef = new AtomicReference<>(); // Stub the setter to store the value doAnswer(invocation -> { String name = invocation.getArgument(0, String.class); usernameRef.set(name); return null; }).when(mockedUser).setUsername(anyString()); // Stub the getter to return the stored value when(mockedUser.getUsername()).thenAnswer((Answer<String>) invocation -> usernameRef.get()); // Inject mock into the service UserService service = new UserService(mockedUser); // Change the username via service service.changeUsername("Thomas"); assertEquals("Hello, Thomas", service.greetUser()); // Change again and check service.changeUsername("Jane"); assertEquals("Hello, Jane", service.greetUser()); } }
In this example, a mock User
object is created, and an AtomicReference
is used to mimic the internal state of the username
field. The doAnswer()
method captures and stores the value passed to the setUsername()
method, effectively simulating a state change. The getUsername()
method is then stubbed using thenAnswer()
to return the value stored in the AtomicReference
.
This setup allows the test to verify that the UserService
correctly updates and retrieves the username through the mocked User
object. It also demonstrates how to simulate realistic object behavior without relying on actual field access.
4. Conclusion
In this article, we explored how to stub getter and setter methods using Mockito. We began by creating simple domain and service classes to demonstrate the concept. Then, we showed how to stub a getter using when().thenReturn()
and how to simulate state changes for setters using doAnswer()
in combination with thenAnswer()
.
If you know a more effective way to simulate internal state when stubbing getters and setters in Mockito, beyond using AtomicReference
, we’d greatly appreciate your input. Please share your suggestions or alternative approaches in the comments section below.
5. Download the Source Code
This article explored how to stub getter and setter methods using Mockito.
You can download the full source code of this example here: mockito stub getter setter