junit 如何在一次测试中部分模拟自动布线对象?

h7appiyu  于 2022-11-11  发布在  其他
关注(0)|答案(2)|浏览(168)

我有一个config类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中的一个变量(并在测试后重置它)?

7rtdyuoh

7rtdyuoh1#

我认为你可以使用@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

mu0hgdu0

mu0hgdu02#

你可以覆盖测试的yaml变量。你需要一个测试概要文件application-test.yaml。在那里你可以覆盖你的变量。同样用@ActiveProfiles("test")注解你的测试类。你的测试将使用默认的yaml和覆盖变量,它们在“test”yaml中声明。但是你必须隔离这个测试,它使用不同的yaml参数到另一个测试中。看看这个问题:Load different application.yml in SpringBoot Test

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

您还可以在@SpringBootTest注解中指定属性

@SpringBootTest(
    properties = { "spring.application.name=example", "ENV_VARIABLE=secret" }
)

但是,它们仍然在该类的所有测试用例上传播
这里还有一个@DynamicPropertySource注解,也许它会对你有所帮助。

相关问题