如何对 Spring @Bean CommandLineRunner 进行单元测试?

edw*_*ise 6 java spring unit-testing spring-test spring-boot

我在一个小的 PoC 中使用 Spring Boot,我正在尝试测试 @Bean 实现。我有这个代码:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    CommandLineRunner init(@Value("${db.resetAndLoadOnStartup:true}") boolean resetAndLoadOnStartup,
                           SequenceIdRepository sequenceRepository,
                           UserAccountRepository userAccountRepository,
                           BookRepository bookRepository) {
        return args -> {
            log.info("Init Application...");
            if (resetAndLoadOnStartup) {
                fillDBData(sequenceRepository, userAccountRepository, bookRepository);
            }
            log.info("Aplication initiated!");
        };
    }

    private void fillDBData(SequenceIdRepository sequenceRepository,
                            UserAccountRepository userAccountRepository,
                            BookRepository bookRepository) {
        // Some code...
    }
...
}
Run Code Online (Sandbox Code Playgroud)

我如何对这个@Bean commandLineRunner 进行单元测试?是的,也许我可以对“fillDBData”方法进行单元测试(放置受保护或使用 powermock),但我想了解是否有办法“完全”测试 Spring @Bean。

gyo*_*der 5

以下是如何使用集成测试进行测试。

@RunWith(SpringJUnit4ClassRunner.class)
// Or create a test version of Application.class that stubs out services used by the CommandLineRunner
@SpringApplicationConfiguration(classes = Application.class)
public class CommandLineRunnerIntegrationTest {

    @Autowired
    private CommandLineRunner clr;

    @Test
    public void thatCommandLineRunnerDoesStuff() throws Exception {
        this.clr.run();
        // verify changes...
    }

}
Run Code Online (Sandbox Code Playgroud)

话虽这么说,我的偏好是创建一个实现命令行运行程序的命名服务,然后对其所有依赖项进行模拟,对其进行单元测试。在我看来,测试 Spring 在应用程序加载时是否调用 CommandLineRunner bean 并不重要,重要的是 CommandLineRunner 实现是否适当地调用其他服务。


Edd*_*dez 4

您可以使用OutputCapture它来查看在控制台中打印的内容

@Rule
public OutputCapture outputCapture = new OutputCapture();
Run Code Online (Sandbox Code Playgroud)

在你的测试方法中:

String output = this.outputCapture.toString();
    assertTrue(output, output.contains("Aplication initiated!"));
Run Code Online (Sandbox Code Playgroud)