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

Java 如何对Spring@Bean CommandLineRunner进行单元测试?,java,spring,unit-testing,spring-boot,spring-test,Java,Spring,Unit Testing,Spring Boot,Spring Test,我在一个小PoC中使用Spring Boot,并尝试测试@Bean实现。我有以下代码: @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean CommandLineRunner init(@Value("${

我在一个小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...
    }
...
}

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

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

@Rule
public OutputCapture outputCapture = new OutputCapture();
在您的测试方法中:

String output = this.outputCapture.toString();
    assertTrue(output, output.contains("Aplication initiated!"));

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

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

}

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

创建MyApplication类

package com.company.project;
//imports
@SpringBootApplication(scanBasePackages = "com.company.project")
public class FileToDbApplication {
  public static void main(String[] args) {
    SpringApplication.run(FileToDbApplication.class, args);
  }
}
创建MyCommandLineRunner类

package com.company.project;
//imports
@Component
public class MyCommandLineRunner implements CommandLineRunner {
  @Autowired
  private SurValueService surValueService;

  @Override
  public void run(String... args) {
    System.out.println("App started with " + args.length + " parameters.");
  }
}
创建MyConfiguration类(您可能不需要@EntityScan@EnableJpaRepositories

在src中创建MyCommandLineRunnerTest。test.java

package com.company.project;
//imports
@ExtendWith(SpringExtension.class)
@SpringBootTest
class MyCommandLineRunnerTest {

  @Autowired
  MyCommandLineRunner commandLineRunner;

  @Test
  public void testMain() {
    commandLineRunner.run("input.txt", "input2.txt");
  }
}

我想你必须在这里进行集成测试。是的,我猜是这样,但我不知道如何在测试中“调用”bean:我不是说测试日志…:)我说的是测试a@BeanThanks,我试试看。是的,我更喜欢模仿其他依赖项。
package com.company.project;
//imports
@ExtendWith(SpringExtension.class)
@SpringBootTest
class MyCommandLineRunnerTest {

  @Autowired
  MyCommandLineRunner commandLineRunner;

  @Test
  public void testMain() {
    commandLineRunner.run("input.txt", "input2.txt");
  }
}