1

In my application there are several tasks which have to get executed periodically in production but should not runx in my integration tests. (These classes are annotated with Spring's @Scheduled annotation.) I have two Spring Boot runner classes:

Application, defined as:

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class Application {
    public static void main(String[] args) throws UnknownHostException {
    SpringApplication app = new SpringApplication(Application.class);
    SimpleCommandLinePropertySource source = new SimpleCommandLinePropertySource(args);
    ...
    }

and ApplicationTest, defined as:

@SpringBootApplication
@EnableAsync
public class ApplicationTest {
    public static void main(String[] args) throws UnknownHostException {
        SpringApplication.run(ApplicationTest.class, args);
    }
}

My tests are annotated with the following annotations:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(ApplicationTest.class)
@WebIntegrationTest(randomPort = true)

I'm defining the class ApplicationTest as the @SpringApplicationConfiguration class, which should be used running the test. Unlike the Application class ApplicationTest is missing the required annotation to enable scheduling.

When I run the test using mvn test or even mvn verify, the annotation get's ignored, starting the application using the Application class and thus starting the scheduled tasks.

What am I missing?

2
  • are both Application and ApplicationTest in the same package by any chance? If so, classpath scanning... Having said that, I wouldn't do this but rather enable scheduling with a profile (you could enable the profile in the main method of your Application class to make that transparent. Commented Jan 5, 2016 at 20:43
  • Could you provide a example as an answer, so I can accept it? Commented Jan 5, 2016 at 20:59

1 Answer 1

2

Both classes are probably in the same component scanning unit so since your Application is a @Configuration class the @EnableScheduling is invoked anyway.

You have a couple of things you could do to fix this:

  1. Create a Profile for the scheduling part and enable that only when you run the app
  2. Idem but enable that if the test profile is not active and enable such profile in your test

Here is an example for 1, the advantage is that you don't have to change anything to your tests

@SpringBootApplication
@EnableAsync
public class Application {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setAdditionalProfiles("application");
        SimpleCommandLinePropertySource source = new SimpleCommandLinePropertySource(args);
        ...
    }

    @EnableScheduling
    @Profile("application") // or @Profile("!test") for instance
    static class ApplicationConfiguration {

    }
}

Your ApplicationTest can now go away.

(btw you don't need a main method for your ApplicationTest class, Spring Boot is not going to execute the main method of such class for a test: SpringApplicationConfiguration takes a list of "sources" that are used to build the context).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.