@DirtiesContext Example in Spring Test
November 18, 2019
The Spring @DirtiesContext
removes the dirty ApplicationContext
from context cache associated with the test. The test can modify the context such as modifying the state of singleton bean, modifying the state of an embedded database etc. Using @DirtiesContext
we can clear the context cache and hence subsequent tests that request the same context will get new context. The @DirtiesContext
can be used at class level as well as method level in integration tests classes.
Find the optional elements of
@DirtiesContext
annotation.
methodMode: It is used to configure mode when
@DirtiesContext
is annotated at test method level. Default value of methodMode
is AFTER_METHOD
.
classMode: It is used to configure mode when
@DirtiesContext
is annotated at class level. Default value of classMode
is AFTER_CLASS
.
hierarchyMode: It configures mode when context is configured via
@ContextHierarchy
annotation. The value can be EXHAUSTIVE
and CURRENT_LEVEL
. Default is EXHAUSTIVE
.
Find the supported test phases.
1. BEFORE_METHOD: It is used at method level with
methodMode
. Current context will be removed and recreated just before this method execution.
@ExtendWith(SpringExtension.class) public class MyAppTest { @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) @Test public void testMethod() { ------ } }
methodMode
. Current context will be removed and recreated just after this method execution.
@ExtendWith(SpringExtension.class) public class MyAppTest { @DirtiesContext(methodMode = MethodMode.AFTER_METHOD) @Test public void testMethod() { ------ } }
classMode
. Current context will be removed and recreated before every test method execution of this integration test class.
@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(SpringExtension.class) public class MyAppTest { ------ }
classMode
. Current context will be removed and recreated after every test method execution of this integration test class.
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) @ExtendWith(SpringExtension.class) public class MyAppTest { ------ }
classMode
. In the test class hierarchy, the context will be removed and recreated before current test class execution.
@DirtiesContext(classMode = ClassMode.BEFORE_CLASS) @ExtendWith(SpringExtension.class) public class MyAppTest { ------ }
classMode
. In the test class hierarchy, the context will be removed and recreated after current test class execution.
@DirtiesContext(classMode = ClassMode.AFTER_CLASS) @ExtendWith(SpringExtension.class) public class MyAppTest { ------ }
Now we will discuss using
@DirtiesContext
in our integration test classes in detail.
Contents
Technologies Used
Find the technologies being used in our example.1. Java 11
2. Spring 5.2.0.RELEASE
3. Spring Boot 2.2.0.RELEASE
4. JUnit 5
5. Maven 3.5.2
6. Eclipse 2018-09
Example: methodMode
Here we will create@DirtiesContext
example using its methodMode
element. We have already discussed that at method level we can use BEFORE_METHOD
and AFTER_METHOD
. Find the example to use them in our integration test class.
AppConfig.java
package com.concretepage; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.concretepage") public class AppConfig { }
package com.concretepage; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Component; @Component public class StudentRepository { private List<String> students = new ArrayList<>(); public void addStudent(String name) { students.add(name); } public List<String> getAllStudents() { return students; } public void printAllStudents() { System.out.println(students); } }
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.MethodMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = AppConfig.class) public class MyAppTest1 { @Autowired private StudentRepository studentRepository; @Test public void testMethod1() { studentRepository.addStudent("Krishna"); studentRepository.printAllStudents(); //[Krishna] assertEquals(1, studentRepository.getAllStudents().size()); } @Test public void testMethod2() { studentRepository.addStudent("Mahesh"); studentRepository.printAllStudents(); //[Krishna, Mahesh] assertEquals(2, studentRepository.getAllStudents().size()); } @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) @Test public void testMethod3() { studentRepository.addStudent("Shiva"); studentRepository.printAllStudents(); //[Shiva] assertEquals(1, studentRepository.getAllStudents().size()); } @DirtiesContext(methodMode = MethodMode.AFTER_METHOD) @Test public void testMethod4() { studentRepository.addStudent("Vishnu"); studentRepository.printAllStudents(); //[Shiva, Vishnu] assertEquals(2, studentRepository.getAllStudents().size()); } @Test public void testMethod5() { studentRepository.printAllStudents(); //[] assertEquals(0, studentRepository.getAllStudents().size()); } }
testMethod3()
, context will be cleared before execution of this method. In case of testMethod4()
, context will be cleared after execution of this method. Find the print screen of JUnit test output.

Example: classMode
Here we will create@DirtiesContext
examples using its classMode
element. The classMode
can be assigned the values as BEFORE_EACH_TEST_METHOD
, AFTER_EACH_TEST_METHOD
, BEFORE_CLASS
and AFTER_CLASS
.
Find the example for
BEFORE_EACH_TEST_METHOD
.
MyAppTest2.java
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = AppConfig.class) public class MyAppTest2 { @Autowired private StudentRepository studentRepository; @Test public void testMethod1() { studentRepository.addStudent("Krishna"); studentRepository.addStudent("Mahesh"); studentRepository.printAllStudents(); //[Krishna, Mahesh] assertEquals(2, studentRepository.getAllStudents().size()); } @Test public void testMethod2() { studentRepository.addStudent("Seeta"); studentRepository.addStudent("Geeta"); studentRepository.printAllStudents(); //[Seeta, Geeta] assertEquals(2, studentRepository.getAllStudents().size()); } }
Now find the example for
AFTER_EACH_TEST_METHOD
.
MyAppTest3.java
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = AppConfig.class) public class MyAppTest3 { @Autowired private StudentRepository studentRepository; @Test public void testMethod1() { studentRepository.addStudent("Narendra"); studentRepository.addStudent("Amit"); studentRepository.printAllStudents(); //[Narendra, Amit] assertEquals(2, studentRepository.getAllStudents().size()); } @Test public void testMethod2() { studentRepository.addStudent("Uddhav"); studentRepository.addStudent("Rahul"); studentRepository.printAllStudents(); //[Uddhav, Rahul] assertEquals(2, studentRepository.getAllStudents().size()); } @Test public void testMethod3() { studentRepository.printAllStudents(); //[] assertEquals(0, studentRepository.getAllStudents().size()); } }
Example: hierarchyMode
Here we will create@DirtiesContext
examples using its hierarchyMode
element. It is used to clear context when a context is configured as part of a hierarchy via @ContextHierarchy
. The hierarchyMode
can be assigned the values as CURRENT_LEVEL
and EXHAUSTIVE
.
Definition of
CURRENT_LEVEL
from Spring doc:
"The ApplicationContext for the current level in the context hierarchy and all contexts in subhierarchies of the current level will be removed from the context cache and closed."
Definition of
EXHAUSTIVE
from Spring doc:
"The context cache will be cleared using an exhaustive algorithm that includes not only the CURRENT_LEVEL but also all other context hierarchies that share an ancestor context common to the current test."
Now let us discuss the
@DirtiesContext
examples with hierarchyMode
.
CityConfig.java
package com.concretepage; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class CityConfig { @Bean("city") public List<String> city() { return new ArrayList<>(); } }
package com.concretepage; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class BookConfig { @Bean("book") public List<String> book() { return new ArrayList<>(); } }
CURRENT_LEVEL
.
MyAppTest4.java
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.HierarchyMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextHierarchy; import org.springframework.test.context.junit.jupiter.SpringExtension; @ContextHierarchy({ @ContextConfiguration(classes = CityConfig.class), @ContextConfiguration(classes = BookConfig.class) }) @ExtendWith(SpringExtension.class) public class MyAppTest4 { @Autowired @Qualifier("city") protected List<String> cityList; @Autowired @Qualifier("book") protected List<String> bookList; @DirtiesContext(hierarchyMode = HierarchyMode.CURRENT_LEVEL) @Test public void testMethod1() { cityList.add("Varanasi"); bookList.add("Ramayana"); assertEquals(1, cityList.size()); assertEquals(1, cityList.size()); } @Test public void testMethod2() { assertEquals(1, cityList.size()); } @Test public void testMethod3() { assertEquals(0, bookList.size()); } }
Now find the integration class that is using
EXHAUSTIVE
.
MyAppTest5.java
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.HierarchyMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextHierarchy; import org.springframework.test.context.junit.jupiter.SpringExtension; @ContextHierarchy({ @ContextConfiguration(classes = CityConfig.class), @ContextConfiguration(classes = BookConfig.class) }) @ExtendWith(SpringExtension.class) public class MyAppTest5 { @Autowired @Qualifier("city") protected List<String> cityList; @Autowired @Qualifier("book") protected List<String> bookList; @DirtiesContext(hierarchyMode = HierarchyMode.EXHAUSTIVE) @Test public void testMethod1() { cityList.add("Pyayag"); bookList.add("Mahabharat"); assertEquals(1, cityList.size()); assertEquals(1, cityList.size()); } @Test public void testMethod2() { assertEquals(0, cityList.size()); } @Test public void testMethod3() { assertEquals(0, bookList.size()); } }
References
Spring Testing: @DirtiesContextSpring doc: DirtiesContext