Search code examples
mockitojunit4mybatis-generator

How to configure behaviour of mapper.insertSelective(record) method generated by MyBatisGenerator. using JUnit4 and Mockito?


In my WebApp, I have used MyBatisGenerator to generate mapper interfaces. I have a class UserService as follows:

public class UserService {

    @Autowired
    UserMapper userMapper;

    public int create(UserParams userParams) {

        User user = new User();
        user.setFirstName(userParams.getFirstName());
        user.setLastName(userParams.getLastName());
        user.setUserName(userParams.getUserName());
        user.setGender(userParams.getGender());
        user.setInstitutionName(userParams.getInstitutionName());

        userMapper.insertSelective(user);
        int userId = user.getUserId();//line 10 in method.

        return userId;
     }
}

I have written a test class as follows:

@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest extends SpringBootHelloWorldTests {

    @InjectMocks
    UserService service;

    @Mock 
    UserMapper userMapper;

    @Test
    public void testUserService_create(){

        UserParams userParams=new UserParams();
        int i=service.create(userParams);
        assertNotEquals(i,0);
    }       
}

When I execute this test class I am getting a error because in the UserService class in the create method - line number 10. I am getting a NullPointerException as the userId of the user object is null.

I am aware of the fact that it's not possible to mock method local variables.

If I run this same UserService normally (in WebApp), the userMapper.insertSelective method populates the userId of the user passed into the method.

How can we mock userMapper.insertSelective method so that I can configure it to populate a userId in the user object of my test class test method?


Solution

  • Assuming that insertSelective is a void method you can user doAnswer, to manipulate the argument passed to the mock. (If it is not a void method use when( ... ).thenAnswer( ... ).)

    @Test
    public void testUserService_create() {
    
        Mockito.doAnswer(new Answer<Void>() {
    
            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
    
                User user = (User) invocation.getArguments()[0];
                user.setUserId(5);
    
                return null;
            }}
        ).when(userMapper).insertSelective(Mockito.any(User.class));
    
        UserParams userParams = new UserParams();
    
        int i = service.create(userParams);
        Assert.assertEquals(5, i);
    }