Java 使用ContextRefreshedEvent参数为私有方法创建JUnit

Java 使用ContextRefreshedEvent参数为私有方法创建JUnit,java,spring,spring-boot,junit,Java,Spring,Spring Boot,Junit,我想为这个私有方法创建一个JUnit测试: @Component public class ReportingProcessor { @EventListener private void collectEnvironmentData(ContextRefreshedEvent event) { } } 我试过这个: @SpringBootApplication public class ReportingTest { @Bean ServletWe

我想为这个私有方法创建一个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实现模拟对象的正确方法是什么?

关于为什么不应该/避免为私有方法编写单元测试,存在着大量的争论/见解。看看这个问题,它会帮助你做出决定并提供更多的见解-

但是,如果你想实现你发布的东西;让我详细分析一下考试不及格的几件事

  • 如果使用JUnit 5,则需要使用
    @SpringBootTest
    (如果使用JUnit 5),另外还需要使用
    @RunWith(SpringRunner.class)
    对Spring引导测试进行注释

  • 您不应该在测试中使用
    new
    操作符创建类的实例,让测试上下文使用
    @Autowired
    或任何其他类似机制自动加载它来注入类

  • 要模拟输入参数并调用私有方法,可以使用
    Powermockito
    library。请注意,如果您的场景不需要调用私有方法,那么
    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);
    
        }
    }
    

    为私有方法创建测试是(非常)糟糕的做法。试着重构你的代码,这样你就可以测试它或它会影响的副产品,通过使用mocksCan,你可以告诉我如何模拟它吗?我得到
    java.lang.IllegalStateException:找不到@SpringBootConfiguration,你需要在测试中使用@ContextConfiguration或@SpringBootTest(classes=…)
    是的,这是一个非常常见的错误,当您的spring引导测试无法找到SpringBootApplication类型的类或@Config注释的配置类时,就会发生这种情况,基本上,它需要加载上下文并需要其中一个的位置,更糟糕的是,我找不到解决方案。你知道如何修复吗?你的spring boot项目没有正确设置,我建议你从开始创建一个新项目,以了解你的项目结构可能有什么问题