Java – mockito, strange behavior of @ injectmocks final field
What I saw was a mistake@ Injectmocks does not seem to create a new test topic before each test method@ Mock's place In the following example, if subject If the section is final, @ test fails If it doesn't pass in the end My current solution is to use @ beforeclass, but this is not ideal
Subject. java:
package inject_mocks_test; public class Subject { private final Section section; public Subject(Section section) { this.section = section; } public Section getSection() { return section; } }
Section. java:
package inject_mocks_test; public class Section {}
SubjectTest. java
package inject_mocks_test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; public class SubjectTest { @Mock Section section; @InjectMocks Subject subject; @BeforeMethod public void setup() { MockitoAnnotations.initMocks(this); } @Test public void test1() { assertEquals(section,subject.getSection()); } @Test public void test2() { assertEquals(section,subject.getSection()); } }
Cheers!
Solution
You are using @ injectmocks for constructor injection This works whenever mockito finds that the field is not initialized (null) JUnit creates a new instance of the test class before each test, so JUnit fans (like me) will never encounter such a problem TestNG did not create a new instance of the test class It maintains the state between the test methods, so when mockitoannotations is called the second time When initmocks (this), mockito will find that the subject field has been initialized and will try to use field injection On the other hand, it will be effective until the field is not final
Is this a mistake? I don't believe it - it's a natural result of API design You can add some workarounds
this.subject = null;
In some @ aftermethod methods