在Mockito框架中@Mock和@InjectMocks之间有什么区别?
当前回答
虽然上面的答案已经涵盖了,但我只是试图添加我看到缺失的细节。它们背后的原因(为什么)。
说明:
Sample.java
---------------
public class Sample{
DependencyOne dependencyOne;
DependencyTwo dependencyTwo;
public SampleResponse methodOfSample(){
dependencyOne.methodOne();
dependencyTwo.methodTwo();
...
return sampleResponse;
}
}
SampleTest.java
-----------------------
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassA.class})
public class SampleTest{
@InjectMocks
Sample sample;
@Mock
DependencyOne dependencyOne;
@Mock
DependencyTwo dependencyTwo;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
public void sampleMethod1_Test(){
//Arrange the dependencies
DependencyResponse dependencyOneResponse = Mock(sampleResponse.class);
Mockito.doReturn(dependencyOneResponse).when(dependencyOne).methodOne();
DependencyResponse dependencyTwoResponse = Mock(sampleResponse.class);
Mockito.doReturn(dependencyOneResponse).when(dependencyTwo).methodTwo();
//call the method to be tested
SampleResponse sampleResponse = sample.methodOfSample()
//Assert
<assert the SampleResponse here>
}
}
参考
其他回答
@Mock为你需要的类创建一个模拟实现。 @InjectMock创建类的一个实例,并将用@Mock注释标记的模拟注入其中。
例如
@Mock
StudentDao studentDao;
@InjectMocks
StudentService service;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
这里我们需要服务类的DAO类。因此,我们模拟它并将它注入到服务类实例中。 类似地,在Spring框架中,所有@Autowired bean都可以在jUnits中被@Mock模拟,并通过@InjectMocks注入到bean中。
initmocks (this)方法初始化这些模拟,并为每个测试方法注入它们,因此需要在setUp()方法中调用。
这个链接有一个很好的Mockito框架教程
Mockito所基于的“Mock框架”是一个允许您创建Mock对象的框架(在旧术语中,这些对象可以称为分流,因为它们作为依赖功能的分流) 换句话说,模拟对象用于模拟代码所依赖的真实对象,您可以使用模拟框架创建代理对象。 通过在测试中使用模拟对象,基本上可以从普通的单元测试过渡到集成测试
Mockito是一个在MIT许可下发布的Java开源测试框架,它是一个“模拟框架”,可以让你用干净简单的API编写漂亮的测试。在Java领域中有许多不同的模拟框架,但是基本上有两种主要的模拟对象框架,一种是通过代理实现的,另一种是通过类重映射实现的。
像Spring这样的依赖注入框架允许您在不修改任何代码的情况下注入代理对象,模拟对象期望调用某个方法并返回预期结果。
@InjectMocks注释尝试实例化测试对象实例,并将带有@Mock或@Spy注释的字段注入到测试对象的私有字段中。
initmocks (this)调用,重置测试对象并重新初始化模拟,所以记得在@Before / @BeforeMethod注释中有这个。
可以使用@InjectMocks注释自动将模拟字段注入到测试对象中。
在下面的例子中,@InjectMocks用于将模拟数据映射注入到数据库中。
@Mock
Map<String, String> dataMap ;
@InjectMocks
DataLibrary dataLibrary = new DataLibrary();
@Test
public void whenUseInjectMocksAnnotation_() {
Mockito.when(dataMap .get("aData")).thenReturn("aMeaning");
assertEquals("aMeaning", dataLibrary .getMeaning("aData"));
}
@Mock注释模拟相关对象。
@InjectMocks注释允许将@Mock创建的不同(和相关的)模拟注入到底层对象中。
两者是相辅相成的。
注意,@InjectMocks即将被弃用
弃用@InjectMocks并计划在Mockito 3/4中删除
你可以关注@avp的答案和链接:
为什么你不应该使用InjectMocks注释来自动装配字段