Mockito,@InjectMocks final字段的奇怪行为

7rtdyuoh  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(103)

我看到了我认为是错误的行为。@InjectMocks似乎没有在每个测试方法之前创建一个新的测试主题。而@Mock则是这样做的。在下面的示例中,如果Subject.section是final,则@测试失败。如果不是final,则两个测试都通过。我当前的解决方法是使用@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());        
    }
}


干杯

2vuwiymt

2vuwiymt1#

您正在使用@InjectMocks进行constructor注入。只要Mockito发现字段未初始化(null),这就可以工作。JUnit在每次测试之前都会创建测试类的新示例,所以JUnit粉丝(像我一样)永远不会遇到这样的问题。TestNg不是创建测试类的新示例。它保持测试方法之间的状态,所以当第二次调用MockitoAnnotations.initMocks(this)时,Mockito会发现 subject 字段已经初始化,并尝试使用field注入。另一方面,这将工作,直到字段不是final。
这是一个bug吗?我相信不是--而是API设计的自然结果。一些解决方法是添加

this.subject = null;

字符串
在某些@AfterMethod方法中。

相关问题