简体   繁体   中英

ReflectionTestUtils - Setting field of type [null] on target object

I am new with Unit testing and Mockito. I'm trying to write tests for my Dao class:

@Repository
@NoArgsConstructor
public class UserDaoImpl implements UserDao {
    
    private NamedParameterJdbcTemplate template;
    
    @Value("${users.find.by_id}")
    private String findByIdQuery;
    
    private RowMapper<User> rowMapper = (rs, rowNum) -> {
        User user = new User();
        user.setId(rs.getInt("id"));
        user.setFirstName(rs.getString("firstname"));
        user.setLastName(rs.getString("lastname"));
        user.setEmail(rs.getString("email"));
        user.setPassword(rs.getString("password"));
        user.setEnabled(rs.getBoolean("enabled"));
        return user;
    };

    public UserDaoImpl(NamedParameterJdbcTemplate template) {
        super();
        this.template = template;
    }

    @Override
    public Optional<User> findById(int id) {
        SqlParameterSource param = new MapSqlParameterSource("id", id);
        User user = null;
        try {
            user = template.queryForObject(findByIdQuery, param, BeanPropertyRowMapper.newInstance(User.class));
        } catch (DataAccessException ex) {
            ex.printStackTrace();
        }
        return Optional.ofNullable(user);
    }
}

In my simple test I simply added @Mock anotation for my NamedParameterJdbcTemplate , and trying to put it into the UserDaoImpl :

public class UserDaoTest {
    
    @Mock
    public NamedParameterJdbcTemplate template;
    @InjectMocks
    public UserDao userDao;
    
    @Test
    public void findByIdTest() {
        template = new NamedParameterJdbcTemplate(new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("classpath:db/schema.sql")
                .addScript("classpath:db/test-data.sql")
                .build());
        userDao = new UserDaoImpl();
        ReflectionTestUtils.setField(userDao, "template", template);
        Mockito.when(userDao.findById(1).get().getEmail()).thenReturn("Keanu@gmail.com");
        
        User user = userDao.findById(1).get();
        assertNotNull(user);
        assertEquals("Keanu@gmail.com", user.getEmail());
    }
}

Each time I run the test, I get java.lang.NullPointerException for the field template . Cant find what is the correct way of implementing the test.

The problem is that you are missing the enablement of Mockito annotations in your test. In order to achieve this, you need to either use @RunWith(MockitoJUnitRunner.class) in your test class as follows:

@RunWith(MockitoJUnitRunner.class)
public class UserDaoTest {
    (...)
}

Or you enable Mockito annotations programmatically:

public class UserDaoTest {
    
    @Mock
    public NamedParameterJdbcTemplate template;
    
    @InjectMocks
    public UserDao userDao;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }
    
    @Test
    public void findByIdTest() {
        template = new NamedParameterJdbcTemplate(new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("classpath:db/schema.sql")
                .addScript("classpath:db/test-data.sql")
                .build());
        userDao = new UserDaoImpl();
        ReflectionTestUtils.setField(userDao, "template", template);
        Mockito.when(userDao.findById(1).get().getEmail()).thenReturn("Keanu@gmail.com");
        
        User user = userDao.findById(1).get();
        assertNotNull(user);
        assertEquals("Keanu@gmail.com", user.getEmail());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM