如何在@PostConstruct 之前调用@BeforeMethod 块
How to invoke @BeforeMethod block before @PostConstruct
下面写的是Spring单元测试代码。单元测试 @Before 方法没有被执行。因为它是直接 运行 @PostConstruct 我得到错误 Caused by: java.lang.IllegalArgumentException: rate must be positive
因为默认值是 0.00。我想设置一些值来请求最大限制,以便 postcontstruct 块顺利通过。我的代码有什么问题?请帮忙。
@Component
public class SurveyPublisher {
@Autowired
private SurveyProperties surveyProperties;
@PostConstruct
public void init() {
rateLimiter = RateLimiter.create(psurveyProperties.getRequestMaxLimit());
}
}
public void publish() {
rateLimiter.acquire();
// do something
}
}
//单元测试class
public class SurveyPublisherTest extends AbstractTestNGSpringContextTests {
@Mock
SurveyProperties surveyProperties;
@BeforeMethod
public void init() {
Mockito.when(surveyProperties.getRequestMaxLimit()).thenReturn(40.00);
}
@Test
public void testPublish_noResponse() {
//do some test
}
}
刚刚意识到在 Junit 回调方法之前总是 运行 postConstruct
方法导致 spring 优先。如文档中所述 -
if a method within a test class is annotated with @PostConstruct, that
method runs before any before methods of the underlying test framework
(for example, methods annotated with JUnit Jupiter’s @BeforeEach), and
that applies for every test method in the test class.
解决你的问题-
- 正如@chrylis 上面评论的那样,重构您的
SurveyPublisher
以使用构造函数注入来注入速率限制器。这样你就可以轻松测试了。
- 注入导致问题的 Mock/Spy bean
创建测试配置,为您提供 class 的实例,用作 @ContextConfiguration
@Configuration
public class YourTestConfig {
@Bean
FactoryBean getSurveyPublisher() {
return new AbstractFactoryBean() {
@Override
public Class getObjectType() {
return SurveyPublisher.class;
}
@Override
protected SurveyPublisher createInstance() {
return mock(SurveyPublisher.class);
}
};
}
}
这是最简单的方法。
@Configuration
@EnableConfigurationProperties(SurveyProperties.class)
static class Config {
}
@ContextConfiguration(classes = {
SurveyPublisherTest.Config.class })
@TestPropertySource(properties = { "com.test.survey.request-max-limit=1.00" })
public class SurveyPublisherTest extends AbstractTestNGSpringContextTests {
//Remove this mock
//@Mock
//SurveyProperties surveyProperties;
}
下面写的是Spring单元测试代码。单元测试 @Before 方法没有被执行。因为它是直接 运行 @PostConstruct 我得到错误 Caused by: java.lang.IllegalArgumentException: rate must be positive
因为默认值是 0.00。我想设置一些值来请求最大限制,以便 postcontstruct 块顺利通过。我的代码有什么问题?请帮忙。
@Component
public class SurveyPublisher {
@Autowired
private SurveyProperties surveyProperties;
@PostConstruct
public void init() {
rateLimiter = RateLimiter.create(psurveyProperties.getRequestMaxLimit());
}
}
public void publish() {
rateLimiter.acquire();
// do something
}
}
//单元测试class
public class SurveyPublisherTest extends AbstractTestNGSpringContextTests {
@Mock
SurveyProperties surveyProperties;
@BeforeMethod
public void init() {
Mockito.when(surveyProperties.getRequestMaxLimit()).thenReturn(40.00);
}
@Test
public void testPublish_noResponse() {
//do some test
}
}
刚刚意识到在 Junit 回调方法之前总是 运行 postConstruct
方法导致 spring 优先。如文档中所述 -
if a method within a test class is annotated with @PostConstruct, that method runs before any before methods of the underlying test framework (for example, methods annotated with JUnit Jupiter’s @BeforeEach), and that applies for every test method in the test class.
解决你的问题-
- 正如@chrylis 上面评论的那样,重构您的
SurveyPublisher
以使用构造函数注入来注入速率限制器。这样你就可以轻松测试了。 - 注入导致问题的 Mock/Spy bean
创建测试配置,为您提供 class 的实例,用作
@ContextConfiguration
@Configuration public class YourTestConfig { @Bean FactoryBean getSurveyPublisher() { return new AbstractFactoryBean() { @Override public Class getObjectType() { return SurveyPublisher.class; } @Override protected SurveyPublisher createInstance() { return mock(SurveyPublisher.class); } }; } }
这是最简单的方法。
@Configuration
@EnableConfigurationProperties(SurveyProperties.class)
static class Config {
}
@ContextConfiguration(classes = {
SurveyPublisherTest.Config.class })
@TestPropertySource(properties = { "com.test.survey.request-max-limit=1.00" })
public class SurveyPublisherTest extends AbstractTestNGSpringContextTests {
//Remove this mock
//@Mock
//SurveyProperties surveyProperties;
}