Spring Framework Testing Concepts: Difference between revisions
Line 79: | Line 79: | ||
In Gradle, the active profiles during testing can be set with: | In Gradle, the active profiles during testing can be set with: | ||
For more details on Gradle test configuration see: {{Internal|Testing_with_Gradle_Java_Plugin|Testing with Gradle Java Plugin}} | <syntaxhighlight lang='groovy'> | ||
test { | |||
systemProperty 'spring.profiles.active', 'heavy' | |||
} | |||
</syntaxhighlight> | |||
For more details on Gradle test configuration see: {{Internal|Testing_with_Gradle_Java_Plugin#Passing_System_Properties_to_Tests|Testing with Gradle Java Plugin}} | |||
==Annotations== | ==Annotations== |
Revision as of 21:55, 2 December 2018
External
Internal
Overview
Proper deployment of dependency injection makes both unit and integration testing easier, in that the presence of setter methods and appropriate constructors on classes makes them easier to wire together in a test without having to set up service locator registries or similar structures.
Unit Tests
According to Spring reference documentation, a Spring unit test is a test that does not use a real application context. The unit test should work without such a real application context, and use objects created with the new operator and injected with a direct invocation of the constructor or setter methods.
Spring provides MockEnvironment and MockPropertySource that are useful for developing out-of-container tests. Understand this.
Integration Tests
According to Spring reference documentation, a Spring integration test is a test where dependencies are injected with the help of a real application context, albeit a special, test-oriented implementation of it. Yet, these tests do not rely on the presence of an application server or Spring Boot instance, or a deployment environment. These tests are slower to run than unit tests, but much faster than the equivalent Selenium or remote tests, that rely on deployment in an actual deployment environment.
Spring provides an integration testing framework, named Spring TestContext Framework. The framework is annotation-driven, and aims to provide the following:
- Context management and caching between tests. This generally speeds up successive tests.
- Dependency injection of test fixture instances.
- Transaction management. The tests can be coded assuming existence of a transaction.
- Spring-specific base classes.
Spring TestContext Framework Dependency
dependencies {
testImplementation('org.springframework:spring-test')
}
This dependency declaration assumes that we are using Gradle Spring dependency-management Plugin and a Maven BOM.
Integration Test Programming Model
Spring TestContext Framework requires a specialized test runner, implemented by the SpringRunner class, which is configured with the @RunWith annotation. The SpringRunner class is an extension of JUnit's BlockJUnit4ClassRunner, which provides functionality of the Spring TestContext Framework to standard JUnit tests. The essential piece of the SpringRunner is a TestContextManager instance, which manages a single TestContext and sends signaling events to all registered TestExecutionListeners.
The test application context is loaded and configured based on the configuration specified with @ContextConfiguration. For configuration details, see:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {
AComponent.class,
BComponent.class})
public class AComponentIntegrationTests {
@Autowired
private AComponent aComponent;
@Test
public void realContextInjectsComponent() {
assertNotNull(aComponent);
}
}
Activating Profiles for Integration Tests
The association between integration tests and active profile (profiles) can be declared with the @ActiveProfiles annotation, in the test code:
TODO
In Gradle, the active profiles during testing can be set with:
test {
systemProperty 'spring.profiles.active', 'heavy'
}
For more details on Gradle test configuration see:
Annotations
Output Test stdout and stderr to Console
When building with Gradle, stdout and stderr of the tests being executed will be shown at the console if the following are configured:
- Set testLogging.showStandardStreams of the Java plugin Test task, as shown here: Show stdout and stderr of the Test JVM on the Console.
- Make sure that a slf4j binding is in the test classpath. Spring uses Logback by default, so the following will work: Place Logback Binding on test classpath.
- Place a logback.xml configuration in src/test/resources. At the time of the writing, I was not able to figure out why logging configuration from src/test/resources/application.yml did not work.