Core Java

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.

Download
You can download the full source code of this example here: mockito stub getter setter

Omozegie Aziegbe

Omos Aziegbe is a technical writer and web/application developer with a BSc in Computer Science and Software Engineering from the University of Bedfordshire. Specializing in Java enterprise applications with the Jakarta EE framework, Omos also works with HTML5, CSS, and JavaScript for web development. As a freelance web developer, Omos combines technical expertise with research and writing on topics such as software engineering, programming, web application development, computer science, and technology.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button