【问题标题】:How to invoke @BeforeMethod block before @PostConstruct如何在@PostConstruct 之前调用@BeforeMethod 块
【发布时间】:2019-05-13 05:49:59
【问题描述】:

我在下面写 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
    }

}

//单元测试类

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
    }

}

【问题讨论】:

  • 你是如何从你的测试类运行测试方法的?我没有使用任何@RunWith(MockitoJUnitRunner.class)。你确定你的模拟被注入了你正在测试的课程吗?
  • 我已经更新了测试类。它正在扩展AbstractTestNGSpringContextTests run as TestNG Test 。
  • 干净的答案是重写您的SurveyPublisher 以使用构造函数注入并注入速率限制器,这样您就可以轻松地在测试用例中测试它们。
  • 在您的测试类中创建一个static 配置类。在其中创建一个@Bean 方法,该方法返回您想要的SurveyProperties。您不需要为此进行模拟。或者根据您的测试,不要使用 Spring 并自己创建类和依赖项。

标签: java spring spring-test-mvc


【解决方案1】:

刚刚意识到它总是会在 Junit 回调方法之前运行 postConstruct 方法,因为 spring 优先。如文档中所述 -

如果测试类中的方法使用@PostConstruct 注释,则 方法在底层测试框架的任何之前的方法之前运行 (例如,使用 JUnit Jupiter 的 @BeforeEach 注释的方法),以及 这适用于测试类中的每个测试方法。

解决您的问题 -

  1. 正如@chrylis 上面评论的那样,重构您的SurveyPublisher 以使用构造函数注入来注入速率限制器。这样您就可以轻松地进行测试了。
  2. 注入导致问题的 Mock/Spy bean
  3. 创建测试配置,为您提供类的实例以用作@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);
                }
            };
        }
    }
    

【讨论】:

    【解决方案2】:

    这是一个简单的工作。

    @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;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-04-06
      • 2023-03-26
      • 2021-06-06
      • 1970-01-01
      • 2012-03-09
      • 2012-02-04
      • 1970-01-01
      • 2015-07-19
      • 2019-07-01
      相关资源
      最近更新 更多