繁体   English   中英

如何在 Junit(Springboot)中模拟 BeanPropertyRowMapper?

[英]How to mock BeanPropertyRowMapper in Junit (Springboot)?

我正在为 Email DAO 层编写一个测试用例。 这就像:

@Repository
@PropertySource({ "classpath:/query.properties" })
public class DaoLayerImpl implements DaoLayerDao {

    /** The jdbc template. */
    @Qualifier("mariaJdbcTemplate")
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /** The find staged query. */
    @Value("${someQuery}")
    String someQuery;

    @Override
    public List<SomeBean> getData() throws MariaDbException {

        List<SomeBean> listOfData = new ArrayList<>();
        try {
            listOfData = jdbcTemplate.query(someQuery,
                    new BeanPropertyRowMapper<SomeBean>(SomeBean.class));
        } catch (RuntimeException e) {
            logger.error("RuntimeException in ", e);
        }

        return listOfData;
    }
}

该层的测试用例是:

@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@PropertySource("classpath:application-test.properties")
public class EmailDaoLayerTest {

    @MockBean
    JdbcTemplate jdbcTemplate;

    @InjectMocks
    DaoLayerImpl dao;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        jdbcTemplate = Mockito.mock(JdbcTemplate.someQuery);
        ReflectionTestUtils.setField(dao, "jdbcTemplate", jdbcTemplate);

    }

    @Test
    public void testCaseForGetData() throws Exception {
        List<SomeBean> beanObject = new ArrayList<>();
        beanObject.add(new SomeBean());
        beanObject.add(new SomeBean());
        beanObject.add(new SomeBean());

        System.out.println(beanObject.size()); // 3

        when(jdbcTemplate.query("someQuery",
                new BeanPropertyRowMapper<SomeBean>(SomeBean.class))).thenReturn(beanObject);


        List<SomeBean> obj = dao.getData();

        System.out.println(obj.size()); //0

        System.out.println("Done");

    }

}

模拟对象大小后变为 0 而不是 3。返回前对象的大小为 3。当我实际访问 DAO 时,对象的大小变为 0,而我已经模拟了 jdbc 模板使用 when-then。

模拟 Bean Property Row Mapper 类的正确方法是什么?

让我回答这个问题然后批评你的方法,也许这有助于更好地理解解决方案最终应该是什么样子。

所以回答你的问题:

从技术上讲,您可能可以执行以下操作:

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.any;
...
Mockito.when(jdbcTemplate.query(eq("someQuery"), 
any(BeanPropertyRowMapper.class)).thenReturn(....);

但是,您应该问问自己,您到底想在这里测试什么? 您在这里有一个相对昂贵的集成测试,它运行 Spring 上下文(它与 SpringRunner 一起工作)并在后台创建许多对象。

然而,基于要测试的方法——我没有看到有任何“有意义的”(受测试)代码要测试。 您可以测试给定查询,BeanPropertyRowMapper 确实可以将响应转换为SomeBean的实例,但是您再次模拟它并且它并没有真正运行。

您可以检查您准备的查询是否针对数据库运行并返回预期结果,但您似乎没有在这里准备任何数据库。

因此,如果目的是覆盖——那么是的,你将被覆盖,但测试不是关于覆盖,而是关于让你“确定”你的代码正常工作。 在这种情况下,运行 Spring Driven 集成测试(带有应用程序上下文和所有内容)似乎是一个巨大的矫枉过正, MockitoRunner可以完成这项工作

暂无
暂无

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

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