gpt4 book ai didi

spring - 如何在 SpringJunit4TestRunner 中将 @ComponentScan 与特定于测试的 ContextConfigurations 一起使用?

转载 作者:IT老高 更新时间:2023-10-28 13:53:55 24 4
gpt4 key购买 nike

我正在测试一个 Spring Boot 应用程序。我有几个测试类,每个测试类都需要一组不同的模拟或其他自定义 bean。

这是设置的草图:

src/main/java:

package com.example.myapp;

@SpringBootApplication
@ComponentScan(
basePackageClasses = {
MyApplication.class,
ImportantConfigurationFromSomeLibrary.class,
ImportantConfigurationFromAnotherLibrary.class})
@EnableFeignClients
@EnableHystrix
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}

package com.example.myapp.feature1;

@Component
public class Component1 {
@Autowired
ServiceClient serviceClient;

@Autowired
SpringDataJpaRepository dbRepository;

@Autowired
ThingFromSomeLibrary importantThingIDontWantToExplicitlyConstructInTests;

// methods I want to test...
}

src/test/java:

package com.example.myapp;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
@ActiveProfiles("test")
public class Component1TestWithFakeCommunication {

@Autowired
Component1 component1; // <-- the thing we're testing. wants the above mock implementations of beans wired into it.

@Autowired
ServiceClient mockedServiceClient;

@Configuration
static class ContextConfiguration {
@Bean
@Primary
public ServiceClient mockedServiceClient() {
return mock(ServiceClient.class);
}
}

@Before
public void setup() {
reset(mockedServiceClient);
}

@Test
public void shouldBehaveACertainWay() {
// customize mock, call component methods, assert results...
}
}

package com.example.myapp;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
@ActiveProfiles("test")
public class Component1TestWithRealCommunication {

@Autowired
Component1 component1; // <-- the thing we're testing. wants the real implementations in this test.

@Autowired
ServiceClient mockedServiceClient;

@Before
public void setup() {
reset(mockedServiceClient);
}

@Test
public void shouldBehaveACertainWay() {
// call component methods, assert results...
}
}

上述设置的问题在于 MyApplication 中配置的组件扫描获取了 Component1TestWithFakeCommunication.ContextConfiguration,因此即使在我想要真正的 ServiceClient 实现的 Component1TestWithRealCommunication 中,我也会得到一个模拟 ServiceClient。

虽然我可以在两个测试中使用@Autowired 构造函数并自己构建组件,但有足够数量的复杂设置我宁愿为我设置 Spring TestContext(例如,Spring Data JPA 存储库,来自应用程序外部库的组件,这些组件从 Spring 上下文中提取 bean 等)。在测试中嵌套一个可以在 Spring 上下文中本地覆盖某些 bean 定义的 Spring 配置感觉应该是一种干净的方法;唯一的缺点是这些嵌套配置最终会影响所有基于 MyApplication 配置的 Spring TestContext 测试(哪个组件扫描应用程序包)。

如何修改我的设置,以便在每个测试类中只使用几个本地覆盖的 bean 来为我的测试获得“大部分真实”的 Spring 上下文?

最佳答案

以下内容应该可以通过引入仅适用于当前测试类的新 fake-communication profile 来帮助您实现目标。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
@ActiveProfiles({"test", "fake-communication"})
public class Component1TestWithFakeCommunication {

// @Autowired ...

@Profile("fake-communication")
@Configuration
static class ContextConfiguration {
@Bean
@Primary
public ServiceClient mockedServiceClient() {
return mock(ServiceClient.class);
}
}
}

关于spring - 如何在 SpringJunit4TestRunner 中将 @ComponentScan 与特定于测试的 ContextConfigurations 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39300167/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com