Junit测试调用Dao类的Business类

Posted

技术标签:

【中文标题】Junit测试调用Dao类的Business类【英文标题】:Junit test the Business class that invokes Dao class 【发布时间】:2017-01-24 05:36:00 【问题描述】:

我正在接管一个使用 Struts 和普通 JDBC 框架实现的产品。我计划在项目中实施 Junit 测试以加快测试速度。仅供参考,该项目尚未投入生产。这仍处于开发阶段,但使用的是非常古老的技术。该项目没有任何接口和相应的实现。像旧的编程一样,该类被直接实例化并照此使用。所以,不能使用 mockito 框架。由于所有这些限制,我需要将 TDD 开发到项目中。我不能完全废弃并用新技术开发它。

我的问题是:我正在为业务层编写一个 junit 测试,以检查该方法是否有效。这个商务舱也在打电话给 DAO。由于在测试时未创建数据库连接,因此会出现连接错误。如何编写 junit 测试来仅测试业务层?我是否需要在测试方法中包含 DAO 连接?如果是,我该如何实现?

我是 Junit 和 TDD 的新手。因此,如果我的理解有误或解决此问题,请指导我。

【问题讨论】:

答案很好,只是想补充一下,您可能想看看在测试期间是否可以连接到这些现代内存数据库之一。据我了解,它们非常适合单元测试,让您不必断开数据库连接。 【参考方案1】:

你能重构你的代码吗?如果是这样,您可以从重构代码开始,为您的真实 DAO 定义 DAO 接口,实现新创建的接口的模拟版本,并在单元测试中将它们注入您的服务。

在没有任何框架的情况下将 DAO 注入服务类的最简单方法可能是构造函数注入,即将 DAO 实例传递给服务类构造函数。

public class YourService 
    private final YourDAOInterface dao;

    public YourService(YourDAOInterface dao) 
        this.dao = dao;
    

这里的构造函数dao的参数可以是真正的DAO,也可以是用于测试的mock实现(需要让这两个DAO实现相同的接口YourDAOInterface)。

【讨论】:

【参考方案2】:

我建议在做任何其他事情之前重构到可测试的状态。如果设计真的像你说的那么糟糕,那么现在有办法为特定的类编写一个有用的测试。

【讨论】:

【参考方案3】:

我想,您写的第一段与您最终在第二段中提出的问题无关。

我们称之为单元测试是有原因的——因为我们只测试一个单元——它不是集成测试。我们不会在这里混淆图层。

如果您的目标是仅测试业务层 - 您仅测试业务层并模拟下面的所有内容(如 DAO 等)。因此,通过使用一些模拟框架(Mockito、PowerMock、JMockit 等)向您的业务层代码提供数据,并假设您的 DAO 层是正确的。

通过使用模拟框架,您向业务功能提供相同的数据,DAO 层应该从数据库移交,而您根本不执行 DAO 层。除了 JUnit 之外,您还需要这些模拟 API 来正确编写单元测试。

对有关使用内存数据库和框架(Apache DBUnit 和 H2 DB 都在那里)的问题的评论,但是在为 DAO 层而不是业务层编写单元测试时,您将需要这些。

正如其他答案中所建议的,始终建议重构并使代码可测试。

希望对你有帮助!!

【讨论】:

是的,我知道应该使用模拟框架来模拟DAO对象。我必须以可以使用模拟的方式修改设计,因为当前的设计没有接口和实现。您能否参考一个链接,我可以在其中找到 DAO 类的模拟? 您需要展示您的服务层和 dao 层代码的示例。如果您的 DAO 对象是服务层的依赖项,则首先创建该 dao 依赖项的模拟对象,然后使用该模拟对象返回服务层使用的测试数据。实际语法因 API 而异。您决定使用哪个模拟 API 了吗?

以上是关于Junit测试调用Dao类的Business类的主要内容,如果未能解决你的问题,请参考以下文章

使用 JUnit 和 Mockito 对 DAO 类进行单元测试

如何编写单元测试 (JUnit) 以使用 DAO 类检查数据库连接?

在 Junit 5 中,如何从扩展中调用测试类方法?

JUnit4 中静态内部测试类的嵌套测试设置

Ktor:使用 JUnit 测试类的 Spek/KotlinTest 测试 REST 端点

shop--5.使用Junit进行验证