What it does: @RunWith (SpringJUnit4ClassRunner.class)

What does this annotation do?
When would I like to use this?
When would I not want to use this?

@RunWith(SpringJUnit4ClassRunner.class) 

I can find more cases of using this when I am Google and cannot find explanation 101 of what this annotation should tell me or when / why I will use it?

+21
spring junit
source share
3 answers

Annotations are used to configure a unit test that requires Spring dependency injection.

From Spring Link - 10. Node Testing :

10.1 Creating the unit test class

For the unit test to run a batch job, the environment must load the ApplicationContext job. Two annotations are used to launch it:

@RunWith (SpringJUnit4ClassRunner.class): indicates that the class should use Spring JUnit tools.

@ContextConfiguration (locations = {...}): Indicates which XML files contain ApplicationContext.

+15
source share

If you use annotations, not XML files, then any class for which you conduct unit testing that requires the implementation of Spring dependencies should be included in the @ContextConfiguration annotation. For example:

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = FooManager.class) class FooManagerTest { @Autowired FooManager fooManager; 

Now that you use fooManager in a unit test, the Spring context will be configured for it.

If fooManager automatically connects to any bean components, then these bean classes must also be in the @ContextConfiguration annotation. Therefore, if the FooManager bean is automatically connected to the FooReporter bean:

 @ContextConfiguration(classes = {FooManager.class, FooReporter.class}) 

If the beans that fooManager automatically binds contain state, then you probably want to reset the state of these beans for each test. In this case, you can add the @DirtiesContext annotation to your test class:

 @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) 

If fooManager or any of its auto-wiring components reads Spring config, then you need to add the list of initializers to the @ContextConfiguration annotation, which contains the ConfigFileApplicationContextInitializer class:

 @ContextConfiguration(classes = FooManager.class, initializers = ConfigFileApplicationContextInitializer.class) 
+3
source share

To answer the question when you want and do not want to use it is part of the question.

When to use SpringJUnit4ClassRunner

IMO SpringJUnit4ClassRunner should be used very sparingly. Running the Spring container to run the unit test involves significant overhead.

I usually use SpringJUnit4ClassRunner to check:

  • that the components are inserted (automatically connected), as expected
  • this configuration data is entered as expected

At the very least, I always have a simple SpringJUnit4ClassRunner test to test the health of the Spring container. Ok

Component injection can cause problems if the @Qualifier annotation @Qualifier not used or is being used incorrectly. A health check test will detect such problems.

When loading a configuration from multiple yaml files, you may need to verify that the cards are combined, as expected, with the appropriate overrides.

When not to use SpringJUnit4ClassRunner

I would not use SpringJUnit4ClassRunner to test non-Spring functions in the test code. Which in my experience means most of the functionality.

Thus, this means that any automatically connected components and entered configuration data must be checked. This may mean a little setup code for your unit tests. However, this installation code needs to be written only once for all tests in the tested class. It is also much faster to run unit tests with proven components.

I keep mocking and using Spock to make fun of the ingredients. Example winding code:

 import spock.lang.Specification class FooManagerTest extends Specification { FooManager cut void createMockFooReporter() { FooReporter mockFooReporter = Mock(FooReporter) mockFooReporter.fooFormatter = Mock(FooFormatter) } void setup() { cut = new FooManager() cut.fooReporter = createMockFooReporter() } void "Basic test"() { // Do a basic test using 'cut' } } 

In this example, the FooManager class under test has a FooReporter FooReporter , which itself contains a FooFormatter FooFormatter .

0
source share

All Articles