在Mockito框架中@Mock和@InjectMocks之间有什么区别?
当前回答
@Mock用于声明/模拟依赖bean的引用,而@InjectMocks用于模拟正在为其创建测试的bean。
例如:
public class A{
public class B b;
public void doSomething(){
}
}
A类测试:
public class TestClassA{
@Mocks
public class B b;
@InjectMocks
public class A a;
@Test
public testDoSomething(){
}
}
其他回答
@Mock创建一个mock。@InjectMocks创建类的一个实例,并将使用@Mock(或@Spy)注释创建的模拟注入到该实例中。
注意,您必须使用@RunWith(MockitoJUnitRunner.class)或Mockito.initMocks(this)来初始化这些模拟并注入它们(JUnit 4)。
在JUnit 5中,必须使用@ExtendWith(MockitoExtension.class)。
@RunWith(MockitoJUnitRunner.class) // JUnit 4
// @ExtendWith(MockitoExtension.class) for JUnit 5
public class SomeManagerTest {
@InjectMocks
private SomeManager someManager;
@Mock
private SomeDependency someDependency; // this will be injected into someManager
// tests...
}
虽然上面的答案已经涵盖了,但我只是试图添加我看到缺失的细节。它们背后的原因(为什么)。
说明:
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>
}
}
参考
使用@Tom提到的方法的一个好处是,您不必在SomeManager中创建任何构造函数,从而限制客户端实例化它。
@RunWith(MockitoJUnitRunner.class)
public class SomeManagerTest {
@InjectMocks
private SomeManager someManager;
@Mock
private SomeDependency someDependency; // this will be injected into someManager
//You don't need to instantiate the SomeManager with default contructor at all
//SomeManager someManager = new SomeManager();
//Or SomeManager someManager = new SomeManager(someDependency);
//tests...
}
这是否是一个好的实践取决于你的应用程序设计。
Mockito所基于的“Mock框架”是一个允许您创建Mock对象的框架(在旧术语中,这些对象可以称为分流,因为它们作为依赖功能的分流) 换句话说,模拟对象用于模拟代码所依赖的真实对象,您可以使用模拟框架创建代理对象。 通过在测试中使用模拟对象,基本上可以从普通的单元测试过渡到集成测试
Mockito是一个在MIT许可下发布的Java开源测试框架,它是一个“模拟框架”,可以让你用干净简单的API编写漂亮的测试。在Java领域中有许多不同的模拟框架,但是基本上有两种主要的模拟对象框架,一种是通过代理实现的,另一种是通过类重映射实现的。
像Spring这样的依赖注入框架允许您在不修改任何代码的情况下注入代理对象,模拟对象期望调用某个方法并返回预期结果。
@InjectMocks注释尝试实例化测试对象实例,并将带有@Mock或@Spy注释的字段注入到测试对象的私有字段中。
initmocks (this)调用,重置测试对象并重新初始化模拟,所以记得在@Before / @BeforeMethod注释中有这个。
很多人已经在这里给出了关于@Mock和@InjectMocks的很好的解释。我喜欢它,但我认为我们的测试和应用程序应该以这样一种方式编写,我们不应该使用@InjectMocks。
进一步阅读的示例参考:https://tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-annotation-to-autowire-fields/
推荐文章
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- 单元测试反模式目录
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?