I'm using Spring Boot in a little PoC, and I'm trying to test a @Bean implementation. I have this code:
@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...
}
...
}
How can I unit test this @Bean commandLineRunner? Yeah, maybe I could unit test the 'fillDBData' method (putting protected or with powermock), but I would like to learn if there's a way to test the Spring @Bean "completely".
Here's how you could test with an integration test.
@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...
}
}
That being said, my preference would be to create a named service that implements command line runner and then unit test it with all of its dependencies mocked out. In my opinion, it's not critical to test that Spring is going to call the CommandLineRunner bean when the application loads, but that the CommandLineRunner implementation calls other services appropriately.
You can use OutputCapture
to see what you print in the console
@Rule
public OutputCapture outputCapture = new OutputCapture();
in your test method:
String output = this.outputCapture.toString();
assertTrue(output, output.contains("Aplication initiated!"));
Create MyApplication class
package com.company.project;
//imports
@SpringBootApplication(scanBasePackages = "com.company.project")
public class FileToDbApplication {
public static void main(String[] args) {
SpringApplication.run(FileToDbApplication.class, args);
}
}
Create MyCommandLineRunner class
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.");
}
}
Create MyConfiguration class (you may not need @EntityScan and @EnableJpaRepositories )
package com.company.project;
//imports
@SpringBootConfiguration
@ComponentScan("com.company.project")
@EnableAutoConfiguration
@EntityScan(basePackages = "com.company.project.model")
@EnableJpaRepositories(basePackages = "com.company.project.service")
public class MyConfiguration {
}
Create MyCommandLineRunnerTest in src. 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");
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.