Prevent Application / CommandLineRunner classes from executing during JUnit testing

If in your TestCase class there is this annotations:

@SpringApplicationConfiguration(classes = {Application.class})

this will cause the Application.class, implementing the CommandLineRunner interface, to run the required method

public void run(String... args) throws Exception

I still think this is, mostly, a not wanted behaviour, since in your test environment you may not want to launch the entire application.

I have in mind two solution to circumvent this problem:

  1. to remove the CommandLineRunner interface from my Application class
  2. to have a different context for testing

Both this solution requires lot of coding. Do you have a more convenient solution?


Jan's solution can be achieved easier.

In your test class, activate the "test" profile:

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
public class MyFancyTest {}

In your CommandLineRunner set the profile to NOT test:

@Component
@Profile("!test")
public class JobCommandLineRunner implements CommandLineRunner {}

Then you don't have to manually set the profile in the Application.


As mentioned in spring documentation http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html you can use @ContextConfiguration with a special initializer:

ConfigFileApplicationContextInitializer is an ApplicationContextInitializer that can apply to your tests to load Spring Boot application.properties files. You can use this when you don’t need the full features provided by @SpringApplicationConfiguration.

In this example anyComponent is initialized and properties are injected, but run(args) methods won't be executed. (Application.class is my main spring entry point)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class, 
                      initializers = ConfigFileApplicationContextInitializer.class)
public class ExtractorTest {
    @Autowired
    AnyComponent anyComponent;

    @Test
    public void testAnyComponent() {
       anyComponent.anyMethod(anyArgument);
    }
}

You can define a test configuration in the same package as your application that looks exactly the same, except that it excludes beans implementing CommandLineRunner. The key here is @ComponentScan.excludeFilters:

@Configuration
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CommandLineRunner.class))
@EnableAutoConfiguration
public class TestApplicationConfiguration {
}

Then, just replace the configuration on your test:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestApplicationConfiguration.class)
public class SomeApplicationTest {
    ...
}

No CommandLineRunner will be executed now, because they are not part of the configuration.