【问题标题】:When to use a new operator to create obj and when to use autowired annotation to test a class?何时使用 new 运算符创建 obj 以及何时使用自动装配注解来测试类?
【发布时间】:2019-01-09 02:06:02
【问题描述】:

我要测试的类名为UserService,带有sendEmail 方法,它会向用户发送一封电子邮件。

要完成这项任务,它依赖于EmailService。现在,当编写一个测试用例来测试这个时——我应该创建UserService userService = new UserService() 并模拟电子邮件服务还是创建上下文文件在我的测试类中定义UserService bean 和@Autowired UserService 并模拟EmailService

这两种方法有什么区别,我什么时候应该使用另一种?其中哪一个是真实的对象?

【问题讨论】:

  • This discussion 关于使用@Autowired vs 构造函数注入可能会有所帮助。将单元测试与生产代码一样对待,并尽可能保持精简。在这种情况下,第二个选项使单元测试 Spring 知道哪个 IMO 使单元测试比它需要的更复杂。

标签: java spring mockito spring-test


【解决方案1】:

如果你的类是一个 bean,例如你也期望注入依赖,你应该new 操作符创建实例。请查看inject-doesnt-work-with-new-operator answer

您可以创建 TestConfig.class 并模拟 UserService 的依赖项(使用您喜欢的模拟框架 - 我更喜欢 mockito)。在这个 TestConfig 中,你创建你的 bean:

@Configuration
 public static class TestConfig {

   @Bean
   private EmailService emailService() {
       return Mockito.mock(EmailService.class);
   }

   //Assuming that you have constructor injection.
   @Bean
   public UserService userService() {
     return new UserService(emailService());
   }
}

【讨论】:

  • 如果你想要一个简单的单元测试,构建你自己的实例并且不依赖 spring 做所有的连接是完全可以的。理想情况下,你应该同时做这两个(一个是单元测试,另一个或多或少是集成测试)。
  • @M.Deinum 如果有可能 Bean 也被用作 Spring 框架之外的 POJO 类。请给我一个具体的例子,这很好吗?另外,如果您创建要测试的类的实例,而不让 spring 进行布线,它不再是集成测试了吗?提前致谢。
  • 我在哪里说这是一个集成测试?我什至说那是一个单元测试而不是集成测试)。
  • 我不想把这个变成讨论,但我真的很想理解。 (如果我错了,请纠正我)我认为你暗示,让 spring 进行依赖连接将是集成测试的一个案例,因为你写道“理想情况下你应该同时做两个(一个是单元测试另一个或多或少是集成测试)。”如果您回答了我的后续问题,那您也将非常好:为什么我们需要对一个类进行一次作为 POJO 和一次作为 bean 的单元测试?有什么真实的例子可以提供吗?
  • 如果你有一些复杂的业务逻辑,你首先要确保它是独立工作的(单元)。如果您不这样做,您的测试可能会因设置问题和错误配置而变得模糊不清。更不用说单元测试通常比完整的集成测试快得多。接下来你想要一个集成测试(或者更确切地说是一个系统测试)。您发送一个请求并在一次调用中从头到尾测试所有内容。检查消息是否被发送,是否保存在数据库等中。
猜你喜欢
  • 2019-01-07
  • 1970-01-01
  • 2019-05-17
  • 2013-02-14
  • 1970-01-01
  • 1970-01-01
  • 2021-10-17
  • 2013-02-12
  • 2012-09-19
相关资源
最近更新 更多