0

I’m looking for some guidance on the best way of writing integration (ie tests for entire Spring Boot Application) for Spring Cloud Task. Based on existing documentation and samples I see two approaches for this:

1) Use the standard @SpringBootTest with @TestPropertySource(properties = {"spring.cloud.task.closecontext_enable=false"} as described here

http://docs.spring.io/spring-cloud-task/docs/1.2.0.M2/reference/htmlsingle/#_writing_your_test

This seems to allow effectively only one test per test class as the task is run when the spring context is initialized ie once per test class. However @Autowiring of beans in the context into the test class should work to eg to check the results of the task, or examine the state of the task repository.

2) Use SpringApplication.run(MyTaskApplication.class, myArguments); in each test method as in the example here

https://github.com/spring-cloud/spring-cloud-task/blob/master/spring-cloud-task-samples/batch-job/src/test/java/io/spring/BatchJobApplicationTests.java

This allows me to write multiple tests in the test class each with potentially different spring properties or batch job parameters.

The main problem I have with either approach that I can’t see how to get access eg @Autowire to beans in the context such as JdbcTemplate (eg to insert test input data for a job into an embedded db) or RestTemplate (to set up expectations using MockRestServiceServer) after these beans are created but BEFORE the task is run - is this possible? If not it’s hard to see how to write meaningful integration tests for tasks.

David Geary
  • 1,756
  • 2
  • 14
  • 23

1 Answers1

0

What Ive done for now is a variation on approach (2) above (ie I can run the task more than once / have multiple tests in the same test class)

I'm using

SpringApplication application = new SpringApplication(new Object[] {MyTaskApplication.class, TestConfig.class});

TestConfig is defined with @TestConfiguration in the test class and contains mock beans etc overriding the actual beans

I then use

application.addListeners() 

to add a ContextRefreshedEventListener which allows me to set expectations on mocks (or execute jdbc calls) after the beans are created but before the task is run. (I have a generic Listener class that allows me to pass in the behaviour as a lambda or method reference per bean)

Then run the task with

application.run(args);

(can use different args in different tests)

I can also pass "--spring.cloud.task.closecontext_enable=false" as an argument to keep the application open if i want to verify mocks / db state after the test runs. In this case I close it manually at the end of the test.

If this seems a sensible approach it might be useful if Spring Cloud Task itself provided some sort of generic listener or hook to allow the setting of test state between bean creation and task execution.

David Geary
  • 1,756
  • 2
  • 14
  • 23