我的 Spring Boot 项目使用 JUnit 5。我想设置一个需要启动本地 SMTP 服务器的集成测试,所以我实现了一个自定义扩展:
public class SmtpServerExtension implements BeforeAllCallback, AfterAllCallback {
private GreenMail smtpServer;
private final int port;
public SmtpServerExtension(int port) {
this.port = port;
}
@Override
public void beforeAll(ExtensionContext extensionContext) {
smtpServer = new GreenMail(new ServerSetup(port, null, "smtp")).withConfiguration(GreenMailConfiguration.aConfig().withDisabledAuthentication());
smtpServer.start();
}
@Override
public void afterAll(ExtensionContext extensionContext) {
smtpServer.stop();
}
}
因为我需要配置服务器的端口,所以我在测试类中注册了扩展,如下所示:
@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith(SpringExtension.class)
@ActiveProfiles("test")
public class EmailControllerIT {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Value("${spring.mail.port}")
private int smtpPort;
@RegisterExtension
// How can I use the smtpPort annotated with @Value?
static SmtpServerExtension smtpServerExtension = new SmtpServerExtension(2525);
private static final String RESOURCE_PATH = "/mail";
@Test
public void whenValidInput_thenReturns200() throws Exception {
mockMvc.perform(post(RESOURCE_PATH)
.contentType(APPLICATION_JSON)
.content("some content")
).andExpect(status().isOk());
}
}
虽然这基本上是有效的:我如何使用带smtpPort
注释的@Value
(从test
配置文件中读取)?
更新 1
根据您的建议,我创建了一个自定义TestExecutionListener
.
public class CustomTestExecutionListener implements TestExecutionListener {
@Value("${spring.mail.port}")
private int smtpPort;
private GreenMail smtpServer;
@Override
public void beforeTestClass(TestContext testContext) {
smtpServer = new GreenMail(new ServerSetup(smtpPort, null, "smtp")).withConfiguration(GreenMailConfiguration.aConfig().withDisabledAuthentication());
smtpServer.start();
};
@Override
public void afterTestClass(TestContext testContext) {
smtpServer.stop();
}
}
监听器是这样注册的:
@TestExecutionListeners(value = CustomTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS)
运行测试时,侦听器会被调用,但smtpPort
始终是0
,因此似乎@Value
没有拾取注释。