简体   繁体   English

ReflectionTestUtils - 在目标 object 上设置 [null] 类型的字段

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

I am new with Unit testing and Mockito.我是单元测试和 Mockito 的新手。 I'm trying to write tests for my Dao class:我正在尝试为我的 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 :在我的简单测试中,我只是为我的NamedParameterJdbcTemplate添加了 @Mock 注释,并尝试将其放入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 .每次运行测试时,我都会得到字段templatejava.lang.NullPointerException 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.问题是您在测试中缺少启用 Mockito 注释。 In order to achieve this, you need to either use @RunWith(MockitoJUnitRunner.class) in your test class as follows:为了实现这一点,您需要在测试 class 中使用@RunWith(MockitoJUnitRunner.class) ,如下所示:

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

Or you enable Mockito annotations programmatically:或者您以编程方式启用 Mockito 注释:

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());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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