Mockito,@InjectMocks最终字段的奇怪行为

2022-09-03 18:28:12

我看到的行为我认为是一个错误。@InjectMocks似乎并没有在每个测试方法之前创建一个新的测试对象。@Mock在哪里。在下面的示例中,如果 Subject.section 是最后一个,则@Test失败。如果不是最终的,两者都通过。我目前的解决方法是使用@BeforeClass,但这并不理想。

主题.java:

package inject_mocks_test;
public class Subject {

    private final Section section;

    public Subject(Section section) {
        this.section = section;
    }

    public Section getSection() {
        return section;
    }
}

部分.java:

package inject_mocks_test;

public class Section {}

科目测试.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());        
    }
}

干杯。


答案 1

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

这是一个错误吗?我相信不是 - 而是API设计的自然结果。您的一些解决方法是添加

this.subject = null;

在某些方法中。@AfterMethod


答案 2

推荐