java - 使用 ContextRefreshedEvent 参数为私有(private)方法创建 JUnit

标签 java spring spring-boot junit

我想为此私有(private)方法创建 JUnit 测试:

@Component
public class ReportingProcessor {

    @EventListener
    private void collectEnvironmentData(ContextRefreshedEvent event) {
    }
}

我尝试过这个:

@SpringBootApplication
public class ReportingTest {

    @Bean
    ServletWebServerFactory servletWebServerFactory() {
        return new TomcatServletWebServerFactory();
    }

    @Test
    public void reportingTest() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {


        GenericApplicationContext parent = new GenericApplicationContext();
        parent.refresh();
        ConfigurableApplicationContext context = new SpringApplicationBuilder(Configuration.class).parent(parent).run();
        ContextRefreshedEvent refreshEvent = new ContextRefreshedEvent(context);        

        ReportingProcessor instance = new ReportingProcessor();

        Method m = ReportingProcessor.class.getDeclaredMethod("collectEnvironmentData", ContextRefreshedEvent.class);
        m.setAccessible(true);
        m.invoke(instance, refreshEvent);               
    }
}

但我得到异常:引起:org.springframework.context.ApplicationContextException:由于缺少 ServletWebServerFactory bean,无法启动 ServletWebServerApplicationContext。

为 ContextRefreshedEvent 实现模拟对象的正确方法是什么?

最佳答案

关于为什么不应该/避免为私有(private)方法编写单元测试有很多争论/见解。看看这个问题,它应该可以帮助您做出决定并提供更多见解 - How do I test a private function or a class that has private methods, fields or inner classes?

但是,如果您无论如何都想实现您所发布的目标;让我分解一些未通过测试的事情。

  1. Spring Boot 测试需要用 @SpringBootTest 注解(如果使用 JUnit 5)并另外使用 @RunWith(SpringRunner.class)如果您使用的是 JUnit 4

  2. 您不应该使用 new 创建类的实例。测试中的运算符,让测试上下文使用 @Autowired 自动加载它或任何其他类似的机制来注入(inject)类。

  3. 要模拟您的输入参数并调用私有(private)方法,您可以使用 Powermockito图书馆。请注意,如果您的场景不需要调用私有(private)方法,则 mockito库应该足以满足几乎所有模拟场景。

下面是应该有效的测试:

@SpringBootTest
public class ReportingProcessorTest {

    @Autowired
    ReportingProcessor reportingProcessor;

    @Test
    public void reportingTest() throws Exception {

        ContextRefreshedEvent contextRefreshedEvent = PowerMockito.mock(ContextRefreshedEvent.class);
        Whitebox.invokeMethod(reportingProcessor, "collectEnvironmentData", contextRefreshedEvent);

    }
}

关于java - 使用 ContextRefreshedEvent 参数为私有(private)方法创建 JUnit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58403298/

相关文章:

java - Spring Security基于XML的配置: java. lang.IllegalArgumentException:没有为id "null"映射的PasswordEncoder

java - Spring框架有一个 "POJO implementation"是什么意思

java - 使用 RepositoryRestResource 注释更改 RESTful 端点不起作用

java - Tomcat8 部署时挂起

java - 在 Spring-boot 中启用 ssl 连接

java - 按下按钮时显示返回值?

java - 使用 namespace 前缀解码 soap 响应

Java 字符串输入输出

java - Unicode 字符串读取

java - 严重 : The RuntimeException could not be mapped to a response, 重新抛出到 HTTP 容器 java.lang.NullPointerException