【问题标题】:Testing advantage with dependency injection依赖注入的测试优势
【发布时间】:2016-03-20 03:14:32
【问题描述】:

我最近开始学习 Spring 和依赖注入的概念。我对 Junit 测试和 Mocking 概念有一定的了解,但仍然无法理解依赖注入提供的特定测试相关优势。

例如,我通过以下方式实例化类 Triangle:-

Triangle triangle1 = new Triangle();

现在使用 Spring 进行依赖注入,我按照以下方式进行操作

Triangle triangle2 = (Triangle) beanFactory.getBean("triangle");

假设Triangle 类有一些需要测试的方法。测试triangle1triangle2 的不同方法是什么

【问题讨论】:

  • 使用构造函数注入代替字段注入。然后你仍然可以在你的单元测试中使用new,为依赖提供模拟。
  • 即使您打算使用getBean(1. 使用构造函数注入,2. 自动装配到您的测试类中),也要使用通用签名。

标签: java spring junit dependency-injection


【解决方案1】:

使用 Spring,您无需从工厂中显式查找 bean。相反,容器会在您使用 bean 之前对其进行初始化,因此您的代码不必调用容器本身。

在 Web 应用程序中,通常有 Web 控制器处理将 Web 请求和帖子转换为对业务逻辑的调用、处理以事务方式实现业务逻辑的服务,以及具有每个执行简单查询或更新的方法的数据访问对象。 (所有这些通常都是无状态的,唯一的实例成员是对其他无状态对象的引用,它们可以同时执行多个请求。)每一层的对象都依赖于下一层的对象,Spring在启动时将所有这些对象连接在一起.

如果我有一个使用服务的控制器,Spring 会创建控制器和服务并将服务连接到控制器。应用程序代码从不调用 bean 工厂。

public class SomeWebController {
    private MyBusinessLogicService  myBusinessLogicService;

    public SomeWebController(MyBusinessLogicService myBusinessLogicService) {
        this.myBusinessLogicService = myBusinessLogicService;
    }
    ...
}

单元测试不必知道容器。测试可以通过为其依赖项插入模拟来设置正在测试的对象,方法是创建这些依赖项并直接调用 setter 方法,或者通过创建测试配置并将该插件插入模拟。

如果我有一个不使用 Spring 的控制器,并且它直接使用它的构造函数来实例化服务,那么用模拟来代替服务就更难了。我将不得不做一些类似重构的事情来为服务引入一个工厂方法,并在测试中覆盖它以返回一个模拟。这将在测试中引入样板代码,在这些测试中我必须对我正在测试的类进行子类化,并且我的覆盖范围会出现空白,而覆盖的工厂方法没有被执行。

【讨论】:

  • 感谢您的回复。因此,当我在原始帖子中测试第二个案例时,我会写如下内容:Triangle tester = Mockito.mock(Triangle.class); 我不能为我的第一个案例写同样的东西吗?对容器不可知论如何让我处于有利的境地?
  • @user3559089;一个更充实的例子会有所帮助。 Spring 用于将事物连接在一起,当您只有一个对象作为示例时,很难看出问题所在。
  • 你能给我一个充实的例子吗?我不知道你在想什么样的例子......谢谢!
猜你喜欢
  • 2018-01-27
  • 2021-01-07
  • 2021-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多