如何模拟自动连接对象部分为一个单一的测试?



我有一个配置类AppConfig来接收环境变量并在服务MyService中使用它们

// application.yml
app-config:
env-var1: ${ENV_VAR1:}
env-var2: ${ENV_VAR2:}
env-var3: ${ENV_VAR3:}
env-var4: ${ENV_VAR4:}
env-var5: ${ENV_VAR5:}
// AppConfig.java
@Data
@EnableConfigurationProperties
@ConfigurationProperties(value = "app-config")
public class AppConfig {
private String envVar1;
private String envVar2;
private String envVar3;
private String envVar4;
private String envVar5;
}
// MyService.java
@Slf4j
@Service
public class MyService {
@Autowired
AppConfig appConfig;

public void doSomething() {
log.info(appConfig.getEnvVar1());
log.info(appConfig.getEnvVar2());
// business logic controlled by appConfig.envVar1 and appConfig.envVar2
// other variables not used
}
}

现在我正在为MyService编写单元测试

// MyServiceTest.java
@SpringBootTest
class MyServiceTest {
@Autowired
AppConfig appConfig;
@Autowired
MyService myService;
@BeforeEach
void setUp() {
// reset override
}
@AfterEach
void tearDown() {
// reset override
}
@Test
void doSomething_envVar1() {
// override appConfig.envVar1 only
myService.doSomething()
}
@Test
void doSomething_envVar2() {
// override appConfig.envVar2 only
myService.doSomething()
}
}

我怎么能覆盖AppConfig内只有一个变量只在一个测试(和重置后测试)?

我认为你可以使用@DirtiesContext注释。使用此注释,您可以在每个测试方法结束时重新启动spring上下文。

@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class MyServiceTest {
@Autowired
AppConfig appConfig;
@Autowired
MyService myService;

@Test
void doSomething_envVar1() {
// override appConfig.envVar1 only
myService.doSomething()
}
@Test
void doSomething_envVar2() {
// appConfig.envVar1 is not effected by envVar1() test
// override appConfig.envVar2 only
myService.doSomething()
}
}

更多的例子在baeldung指南:https://www.baeldung.com/spring-dirtiescontext

您可以为测试覆盖yaml变量。您需要一个测试配置文件application-test.yaml。在那里你可以覆盖你的变量。还要用@ActiveProfiles("test")注释测试类。您的测试将使用默认的yaml和重写变量,它们在"test"中声明。yaml。但是您必须将使用不同yaml参数的测试隔离到另一个测试中。看看这个问题:加载不同的应用程序。

@ActiveProfiles("test")
@SpringBootTest
class SpecialMyServiceTest {

也可以在@SpringBootTest注释

中指定属性
@SpringBootTest(
properties = { "spring.application.name=example", "ENV_VARIABLE=secret" }
)

但是,它们仍然在这个类的所有测试用例中传播

还有一个@DynamicPropertySource注释,也许它会帮助你。看看这个页面,也许你会找到合适的解决方案