Java Mockito,@injectmock使用final字段执行奇怪的行为

Java Mockito,@injectmock使用final字段执行奇怪的行为,java,testng,mockito,Java,Testng,Mockito,我看到的行为,我相信是一个错误@InjectMock似乎并没有在每个测试方法之前创建一个新的测试主题。正如@Mock所做的那样。在以下示例中,如果Subject.section是final,则@Test失败。如果不是最后一个,两个都通过。我目前的解决方法是使用@BeforeClass,但这并不理想 Subject.java: package inject_mocks_test; public class Subject { private final Section section;

我看到的行为,我相信是一个错误@InjectMock似乎并没有在每个测试方法之前创建一个新的测试主题。正如@Mock所做的那样。在以下示例中,如果Subject.section是final,则@Test失败。如果不是最后一个,两个都通过。我目前的解决方法是使用@BeforeClass,但这并不理想

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());        
    }
}

干杯。

您正在将
@InjectMocks
用于构造函数injection。只要Mockito找到未初始化的字段(null),这将起作用。JUnit在每次测试之前都会创建一个新的测试类实例,所以JUnit粉丝(像我一样)永远不会遇到这样的问题。TestNg没有创建测试类的新实例。它保持测试方法之间的状态,因此当第二次调用
MockitoAnnotations.initMocks(this)
时,Mockito将找到已初始化的主题字段,并尝试使用字段注入。在另一个回合,这将起作用,直到场地不是最终的

这是虫子吗?我相信这不是API设计的自然结果。 您的一些解决方法是添加

this.subject = null;

在一些
@AfterMethod
方法中。

您是否使用MockitoJUnitRunner来运行测试用例?不,我使用的是TestNg。您使用的是哪个版本的mockito?mockito版本是1.9.5谢谢,这也可以。但我不明白为什么部分被重新初始化,而主题没有。这是为了向后兼容。在早期版本中(…另一方面,可能有一个增强功能,可以使用类似smth的ForceReinitialization来参数化InjectMock。我还发现了一个针对mockito的TestNG集成。它尚未发布-可能会重置InjectMock字段。或者,使用类可能很有趣,它可以避免使用样板代码来管理lifecyc注释字段上的模拟示例。