如何正确地模块化应用程序配置,以便测试(IT,datajpa,..)不会获取所有用于生产的内容



在我们的应用程序中,我发现我的集成测试比我想要的要多。我想知道,结构正确的应用程序配置是什么样子的,你使用了什么,这样我就可以在测试中@Import只导入那些在生产中使用的、需要的配置。

我认为文件中的相关页面是:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-功能测试弹簧引导应用程序测试用户配置

有人强调,以合理的方式构建代码很重要,但这并没有说明什么。我知道概要文件,可能可以创建在测试和手动导入中不匹配的概要文件,但这可能不是他们谈论的明智方式。

考虑这个主要入口点:

@SpringBootApplication
public class DemoApplication {
private final SomeService someService;
public DemoApplication(SomeService someService) {
this.someService = someService;
}
@EventListener(ApplicationReadyEvent.class)
public void started() {
System.out.println(someService.doIt());
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

某些服务的接口:

public interface SomeService {
public String doIt();
}

和配置:

@Configuration
public class Config {
@Bean
public SomeService createSomeServiceBean() {
return new SomeService() {
@Override
public String doIt() {
return String.format("Hi! (At %s)", LocalDateTime.now());
}
};
}
}

调用时,由@SpringBootApplication注释的入口点将进行组件扫描,发现配置并工作。进一步阅读文档,我们会发现句子:Test slices exclude @Configuration classes from scanning([if@ComponentScan确实有basePackages和basePackagesClasses]的默认值(,但下面的测试:

@SpringBootTest
class DemoApplicationTests {
@Autowired
private SomeService someService;
@Test
void contextLoads() {
System.out.println(someService.doIt());
}
}

只是高兴地发现CCD_ 2 bean已定义。或者这句话只是意味着@DataJpaTest注释的测试不会注册一些配置吗?我有点不清楚,但这似乎不可能,因为@DataJpaTest怎么会知道,哪些配置需要提交,哪些不需要。

同样,我知道如何使用配置文件/排除配置。我在问";构建应用程序的合理方式";。

如何合理地构建你的应用程序,以及如何配置它,以便:

  • @SpringBootApplication带注释的入口点将为生产执行组件扫描、查找和使用配置,但这些配置需要在测试中手动导入
  • 一些包将自动扫描配置,这些配置将在开发和测试环境中使用

Spring Boot Test支持提供注释,只允许使用相关的bean创建Spring Context来测试应用程序的特定切片

使用此功能不需要特定的包结构或命名策略。

以下是其中的一些:

  • @DataJpaTest:您获得了一个带有相关bean的Spring Context来测试您的JPA&lt->数据库接口:EntityManagerDataSource,所有扩展JpaRepository的接口
  • @WebMvcTest:您将获得一个带有模拟servlet环境的Spring Context,用于测试您的web层,其中包括以下bean:所有控制器、控制器建议、WebMvcConfigurerFilter等。但不任何用@Service@Component注释的内容
  • @SpringBootTest:这将为您提供一个完整的Spring上下文,并尝试为您创建所有bean。您可以排除某些自动配置,例如,如果您不希望自动配置生效:

示例:

@SpringBootTest(webEnvironment = RANDOM_PORT)
@TestPropertySource(properties=
{"spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration"})
  • 还有更多的测试切片注释,您可以在这里查看

因此,这些注释在某种程度上是智能的,它们知道应该在上下文中包括哪些bean,以及排除哪些bean。

测试应用程序的一种通用方法是使用上面所述的前两个测试注释来单独验证web和数据层。接下来使用Mockito和普通的JUnit5对您的服务类进行单元测试。最后,编写一些集成测试,使用@SpringBootTest创建整个Spring上下文,以便一起测试所有内容。

最新更新