我已经浏览了一些博客,以了解Mockito注释如何工作的基础知识。
然而,我怀疑何时可以手动实例化用@InjectMocks
注释的字段,即
@InjectMocks
A a = new A();
什么时候依靠MockitoAnnotations.initMocks()
功能来做同样的事情:
@InjectMocks
A a;
这取决于我们用来运行测试用例的JunitTestRunner还是依赖于Mockito框架版本?
答案 0 :(得分:6)
这取决于你是否正在使用(声明)跑步者。
如果你使用跑步者,你不需要自己打电话给MockitoAnnotations.initMocks()
- 跑步者会为你打电话。
通常我们选择跑步者。但是当你想要使用其他跑步者时(比如春天),你可以自己打电话给.initMocks()
。
为了清楚起见,MockitoAnnotations.initMocks(this)
会:
@InjectMocks
@Mock
@Mock
变量的字段中注入@InjectMocks
(或调用其构造函数或使用其setter - 它取决于您使用的依赖注入类型)下面的三个代码示例应该是等效的。
此第一个代码段使用了转轮,无需调用initMocks()
。
@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
@Mock private MyDependency myDependency;
@InjectMocks private MyClass myClass;
@Test
public void myClass_should_get_stuff_from_dependency() {
when(myDependency.getStuff()).thenReturn("stuff!");
assertThat(myClass.getDependencyStuff(), is("stuff!"));
}
}
.initMocks()
:另一个不使用跑步者,因此需要setUp()
方法调用我们的initMocks()
朋友。
// notice there is no runner
public class MyClassTest {
@Mock private MyDependency myDependency;
@InjectMocks private MyClass myClass;
// but now you have to call initMocks() yourself
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void myClass_should_get_stuff_from_dependency() {
when(myDependency.getStuff()).thenReturn("stuff!");
assertThat(myClass.getDependencyStuff(), is("stuff!"));
}
}
@Rule
:最后,正如comments (thanks @StefanBirkner)中指出的那样,自版本1.10.17起,还有可能使用名为JUnit @Rule
的MockitoRule
:
public class MyClassTest {
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Mock private MyDependency myDependency;
@InjectMocks private MyClass myClass;
@Test
public void myClass_should_get_stuff_from_dependency() {
when(myDependency.getStuff()).thenReturn("stuff!");
assertThat(myClass.getDependencyStuff(), is("stuff!"));
}
}
答案 1 :(得分:1)
通常,是否实例化一个用@InjectMocks
注释的对象的决定是代码样式的选择。在大多数情况下,由于Mockito可以处理两种情况,因此没有什么区别。
但是,我在下面概述了一些区别。
@InjectMocks
使测试与对构造函数的更改脱钩。以相同的方式使用依赖注入框架将生产代码与对构造函数的更改解耦。允许Mockito为您实例化该类的实例,从而将测试代码与对构造函数的更改解耦。这意味着将来可以对类构造函数进行任何更改,而不会引起单元测试中的编译错误。
我认为这是@InjectMocks
的最大区别和最大优势。
注意::仅当您使用的代码未遵循最佳做法时,此区别才有意义。
当一个类中有多个构造函数时,Mocktio将调用参数最多的构造函数,即“最大”构造函数。
这只会在以下情况下产生影响
这被认为是不好的做法,因为,
答案 2 :(得分:0)
感谢您的宝贵意见。 但是,当实例化应该通过调用MockitoAnnotations.initMocks()来处理实例化时,它仍然没有回答为什么要手动实例化使用@InjectMocks注释的字段的问题。
尝试运行测试文件时出现以下错误:
引起:org.mockito.exceptions.base.MockitoException:使用@InjectMocks注释的字段'student'为空。 请确保在 MockitoAnnotations.initMocks()之前创建实例; 正确用法示例: class SomeTest { @InjectMocks private Foo foo = new Foo();
@Before public void setUp() {
MockitoAnnotations.initMock(this);
我进一步搜索并发现如果使用较旧版本的Mockito框架则会引发错误。