When running tests using @DirtiesContext
and a test class includes multiple @Nested
classes, the context is dirtied and refreshed after each nested class, even when using the coarsest mode possible level (ClassMode.AFTER_CLASS
).
There is currently no way to specify that @DirtiesContext
should only dirty the context after the top-level class but not after each nested class.
A ClassMode.AFTER_MAIN_CLASS
is suggested to specify the desired functionality.
Comment From: nithril
Would be nice indeed to get control and optimize test execution
Comment From: sbrannen
Hi @jmarchionatto,
Thanks for the proposal, and apologies for not getting to this earlier.
If we were to introduce this support specifically for @Nested
test classes, I'd rather name the new ClassMode
AFTER_ENCLOSING_CLASS
.
However, I investigated our options, and it appears that it might be easier to introduce ClassMode.DISABLED
which could be applied to individual @Nested
test classes. In theory, that approach should also allow ClassMode.DISABLED
to be used on subclasses within a type hierarchy.
In light of that, I've scheduled this for 6.2 M1.
Comment From: jmarchionatto
Sounds good, @sbrannen . Thank you
Comment From: sbrannen
If we were to introduce this support specifically for
@Nested
test classes, I'd rather name the newClassMode
AFTER_ENCLOSING_CLASS
.
After furthering experimentation, this new mode would need to be called AFTER_TOP_LEVEL_CLASS
to signal that the context would only be dirtied after the top-level enclosing class for all @Nested
test classes.
In other words, the AFTER_TOP_LEVEL_CLASS
mode would not apply to the immediately enclosing class for a @Nested
test class nested in another @Nested
test class.
I currently tend to prefer AFTER_TOP_LEVEL_CLASS
over DISABLED
since DISABLED
would have to be applied to every @Nested
class declared directly under a class annotated with @DirtiesContext
; whereas, @DirtiesContext(classMode = AFTER_TOP_LEVEL_CLASS)
would be inherited by all @Nested
test classes that do not override it with a local @DirtiesContext
declaration.
I'm sure the "devil is in the details." 😈
But, a quick prototype reveals that it may be as simple as:
- Creating the
AFTER_TOP_LEVEL_CLASS
enum constant inClassMode
. - Adding the following logic to
AbstractDirtiesContextTestExecutionListener.beforeOrAfterTestClass(...)
.
if (classMode == ClassMode.AFTER_TOP_LEVEL_CLASS && !ClassUtils.isInnerClass(testClass)) {
classMode = ClassMode.AFTER_CLASS;
}
The idea behind the above is that it effectively ignores @DirtiesContext
on a @Nested
test class and coverts the class mode to AFTER_CLASS
for the top-level enclosing class.