【问题标题】:Spring Boot remove @Component when unit testingSpring Boot在单元测试时删除@Component
【发布时间】:2017-01-17 19:53:00
【问题描述】:

请耐心等待,因为这是我第一次使用 Spring Boot,所以这只是我认为正在发生的事情......

我有几个用@Scheduled 注释的方法。它们工作得很好,我已经配置并注入了所有依赖项。这些依赖关系很重,依赖于互联网连接等。我将它们注释为@Lazy,所以它们只在最后一分钟被实例化。

但是,包含预定方法的类需要用@Component 标记,这意味着它们是在启动时创建的。这引发了连锁反应,无论我当前运行的测试是否真的需要它们,都会产生我所有的依赖关系。

当我在 CI 服务器上运行单元测试时,它们会失败,因为服务器没有通过数据库进行身份验证(也不应该)。

测试这些@Scheduled 作业的测试注入了它们自己的模拟,因此它们工作正常。但是,由于仍在创建类,因此完全不相关的测试会导致问题。我显然不想在这些测试中为完全不相关的类创建模拟。

如何防止在测试运行时创建某个 @Component

预定作业类:

package example.scheduledtasks;

@Component
public class ScheduledJob {

    private Database database;

    @Autowired
    public AccountsImporter(Database database) {
        this.database = database;
    }

    @Scheduled(cron="0 0 04 * * *")
    public void run() {
        // Do something with the database
    }
}

配置类:

package example

@Configuration
public class ApplicationConfig {

    @Bean
    @Lazy
    public Database database() {
        return ...;// Some heavy operation I don't want to do while testing.
    }

}

【问题讨论】:

  • 也许this answer 可能会有所帮助。
  • 感谢@Jaims,我已经看到了条件注释,但无法弄清楚我的条件是什么。有什么想法吗?
  • 一种常见的方法是使用不同的配置文件。您有一个带有 @Profile() 注释的 TestConfig 类,它可以将您的数据库模拟为一个轻量级对象。然后在您的测试类中,您可以使用@ActiveProfiles() 来选择您的测试配置。在生产中,您可以提供不同的配置文件。

标签: java spring unit-testing


【解决方案1】:

我知道你说过:

我显然不想在这些测试中为完全不相关的类创建模拟。

不过,正如您所知,您可以轻松地为这个测试覆盖不需要的组件:

@RunWith(...)
@Context...
public class YourTest {
    public static class TestConfiguration {
        @Bean
        @Primary
        public Database unwantedComponent(){
            return Mockito.mock(Database.class);
        }
    }

    @Test
    public void yourTest(){
        ...
    }
}

类似的问题/答案:Override a single @Configuration class on every spring boot @Test

【讨论】:

  • 谢谢亚历克斯。虽然这解决了测试不通过的直接问题,但我仍然认为 Spring 在运行测试时注册计划任务没有意义。测试应该只是我实例化的类,当然?!
  • 这不会从上下文中删除另一个 bean。如果要替换 bean,则需要确保 bean 的名称在测试配置中与通常在 spring 上下文中的名称相同。此答案仅在您尝试将新值注入单值依赖项时才有帮助。
【解决方案2】:

只需将以下内容添加到您的测试类中:

@MockBean
public Database d;

【讨论】:

  • 这太巧妙了!在 Spock 中使用 @SpringBean Database d = Mock()
猜你喜欢
  • 2016-05-28
  • 2015-12-20
  • 1970-01-01
  • 2018-02-20
  • 2016-03-15
  • 2017-02-08
  • 2020-08-08
  • 2020-06-25
相关资源
最近更新 更多