Honor MockReset without @MockitoBean or @MockitoSpyBean fields
Prior to this commit, the static factory methods in MockReset (such as MockReset.before() and MockReset.after()) could only be applied to beans within the ApplicationContext if the test class declared at least one field annotated with either @MockitoBean or @MockitoSpyBean. However, the Javadoc states that it should be possible to apply MockReset directly to any mock in the ApplicationContext using the static methods in MockReset. To address that, this commit reworks the "enabled" logic in MockitoResetTestExecutionListener as follows. - We no longer check for the presence of annotations from the org.springframework.test.context.bean.override.mockito package to determine if MockReset is enabled. - Instead, we now rely on a new isEnabled() method to determine if MockReset is enabled. The logic in the isEnabled() method still relies on the mockitoPresent flag as an initial check; however, mockitoPresent only determines if Mockito is present in the classpath. It does not determine if Mockito can actually be used. For example, it does not detect if the necessary reachability metadata has been registered to use Mockito within a GraalVM native image. To address that last point, the isEnabled() method performs an additional check to determine if Mockito can be used in the current environment. Specifically, it invokes Mockito.mockingDetails().isMock() which in turn initializes core Mockito classes without actually attempting to create a mock. If that fails, that means that Mockito cannot actually be used in the current environment, which typically indicates that GraalVM reachability metadata has not been registered for the org.mockito.plugins.MockMaker in use (such as the ProxyMockMaker). In addition, isEnabled() lazily determines if Mockito can be initialized, since attempting to detect that during static initialization results in a GraalVM native image error stating that Mockito internals were "unintentionally initialized at build time". If Mockito cannot be initialized, MockitoResetTestExecutionListener logs a DEBUG level message providing access to the corresponding stack trace, and MockReset support is disabled. Closes gh-33829
This commit is contained in:
@@ -18,6 +18,9 @@ package org.springframework.test.context.bean.override.mockito;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MockitoResetTestExecutionListener} with a
|
||||
* {@link MockitoBean @MockitoBean} field.
|
||||
@@ -29,15 +32,24 @@ import org.junit.jupiter.api.Test;
|
||||
class MockitoResetTestExecutionListenerWithMockitoBeanIntegrationTests
|
||||
extends MockitoResetTestExecutionListenerWithoutMockitoAnnotationsIntegrationTests {
|
||||
|
||||
// The following mock is not used but is currently required to trigger support for MockReset.
|
||||
// We declare the following to ensure that MockReset is also supported with
|
||||
// @MockitoBean or @MockitoSpyBean fields present in the test class.
|
||||
@MockitoBean
|
||||
StringBuilder unusedVariable;
|
||||
PuzzleService puzzleService;
|
||||
|
||||
|
||||
// test001() and test002() are in the superclass.
|
||||
|
||||
@Test
|
||||
@Override
|
||||
void test002() {
|
||||
super.test002();
|
||||
void test003() {
|
||||
given(puzzleService.getAnswer()).willReturn("enigma");
|
||||
assertThat(puzzleService.getAnswer()).isEqualTo("enigma");
|
||||
}
|
||||
|
||||
|
||||
interface PuzzleService {
|
||||
|
||||
String getAnswer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.test.context.bean.override.mockito;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
@@ -76,7 +75,6 @@ class MockitoResetTestExecutionListenerWithoutMockitoAnnotationsIntegrationTests
|
||||
assertThat(context.getBean(NonSingletonFactoryBean.class).getObjectInvocations).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Disabled("MockReset is currently only honored if @MockitoBean or @MockitoSpyBean is used")
|
||||
@Test
|
||||
void test002() {
|
||||
// Should not have been reset.
|
||||
|
||||
Reference in New Issue
Block a user