use*_*972 404 java unit-testing mocking mockito
Mockito框架@Mock
和之间有什么区别@InjectMocks
?
Tom*_*lst 494
@Mock
创造一个模拟.@InjectMocks
创建类的实例,并将使用@Mock
(或@Spy
)注释创建的模拟注入此实例.
请注意,您必须使用@RunWith(MockitoJUnitRunner.class)
或Mockito.initMocks(this)
初始化这些模拟并注入它们.
@RunWith(MockitoJUnitRunner.class)
public class SomeManagerTest {
@InjectMocks
private SomeManager someManager;
@Mock
private SomeDependency someDependency; // this will be injected into someManager
//tests...
}
Run Code Online (Sandbox Code Playgroud)
ald*_*dok 165
这是关于如何@Mock
和@InjectMocks
工作的示例代码.
说我们有Game
和Player
上课.
class Game {
private Player player;
public Game(Player player) {
this.player = player;
}
public String attack() {
return "Player attack with: " + player.getWeapon();
}
}
class Player {
private String weapon;
public Player(String weapon) {
this.weapon = weapon;
}
String getWeapon() {
return weapon;
}
}
Run Code Online (Sandbox Code Playgroud)
如你所见,Game
上课需要Player
执行attack
.
@RunWith(MockitoJUnitRunner.class)
class GameTest {
@Mock
Player player;
@InjectMocks
Game game;
@Test
public void attackWithSwordTest() throws Exception {
Mockito.when(player.getWeapon()).thenReturn("Sword");
assertEquals("Player attack with: Sword", game.attack());
}
}
Run Code Online (Sandbox Code Playgroud)
Mockito将模拟一个Player类,它的行为使用when
和thenReturn
方法.最后,使用@InjectMocks
Mockito将把它Player
放入Game
.
请注意,您甚至不必创建new Game
对象.Mockito会为你注入它.
// you don't have to do this
Game game = new Game(player);
Run Code Online (Sandbox Code Playgroud)
我们也将使用@Spy
注释获得相同的行为.即使属性名称不同.
@RunWith(MockitoJUnitRunner.class)
public class GameTest {
@Mock Player player;
@Spy List<String> enemies = new ArrayList<>();
@InjectMocks Game game;
@Test public void attackWithSwordTest() throws Exception {
Mockito.when(player.getWeapon()).thenReturn("Sword");
enemies.add("Dragon");
enemies.add("Orc");
assertEquals(2, game.numberOfEnemies());
assertEquals("Player attack with: Sword", game.attack());
}
}
class Game {
private Player player;
private List<String> opponents;
public Game(Player player, List<String> opponents) {
this.player = player;
this.opponents = opponents;
}
public int numberOfEnemies() {
return opponents.size();
}
// ...
Run Code Online (Sandbox Code Playgroud)
那是因为Mockito会检查Type Signature
Game类,这是Player
和List<String>
.
小智 73
在测试类中,测试类应使用@InjectMocks进行注释.这告诉Mockito哪个类注入模拟:
@InjectMocks
private SomeManager someManager;
Run Code Online (Sandbox Code Playgroud)
从那时起,我们可以指定类中的哪些特定方法或对象,在本例中为SomeManager,将替换为mocks:
@Mock
private SomeDependency someDependency;
Run Code Online (Sandbox Code Playgroud)
在此示例中,将模拟SomeManager类中的SomeDependency.
San*_*han 20
例如
@Mock
StudentDao studentDao;
@InjectMocks
StudentService service;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
Run Code Online (Sandbox Code Playgroud)
这里我们需要服务类的dao类.因此,我们模拟它并将其注入服务类实例中.类似地,在Spring框架中,所有@Autowired bean都可以在jUnits中被@Mock模拟,并通过@InjectMocks注入到bean中.
MockitoAnnotations.initMocks(this)方法初始化这些模拟并为每个测试方法注入它们,因此需要在setUp方法中调用它们.
小智 12
@Mock
用于创建和注入模拟实例,而无需手动调用 Mockito.mock。在此示例中,实例为ClassB。
而 @InjectMocks
用于将模拟字段自动注入到测试对象中。在这种情况下,它将是ClassA
ser*_*rup 11
Mockito所基于的"模拟框架"是一个框架,它使您能够创建Mock对象(用旧的术语来说,这些对象可以被称为分流器,因为它们可以作为依赖功能的分流器).换句话说,一个模拟object用于模仿代码所依赖的真实对象,使用模拟框架创建代理对象.通过在测试中使用模拟对象,您实际上是从正常的单元测试到集成测试
Mockito是一个在MIT许可下发布的Java开源测试框架,它是一个"模拟框架",可以让你用干净简单的API编写漂亮的测试.Java空间中有许多不同的模拟框架,但实际上有两种主要类型的模拟对象框架,一种是通过代理实现的,另一种是通过类重映射实现的.
像Spring这样的依赖注入框架允许您在不修改任何代码的情况下注入代理对象,模拟对象期望调用某个方法并返回预期结果.
该@InjectMocks
注释尝试实例测试对象实例,并注入与注释字段@Mock
或@Spy
进入测试对象的私有字段.
MockitoAnnotations.initMocks(this)
调用,重置测试对象并重新初始化模拟,所以请记住在@Before
/ @BeforeMethod
注释中使用它.
dev*_*014 10
@Mock
用于声明/模拟依赖 bean 的引用,而@InjectMocks
用于模拟正在为其创建测试的 bean。
例如:
public class A{
public class B b;
public void doSomething(){
}
}
Run Code Online (Sandbox Code Playgroud)
班级考试A
:
public class TestClassA{
@Mocks
public class B b;
@InjectMocks
public class A a;
@Test
public testDoSomething(){
}
}
Run Code Online (Sandbox Code Playgroud)
使用@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...
}
Run Code Online (Sandbox Code Playgroud)
是否良好实践取决于您的应用程序设计.
尽管上面的答案已经涵盖,但我只是尝试添加我认为缺少的细节。他们背后的原因(The Why)。
插图:
Sample.java
---------------
public class Sample{
DependencyOne dependencyOne;
DependencyTwo dependencyTwo;
public SampleResponse methodOfSample(){
dependencyOne.methodOne();
dependencyTwo.methodTwo();
...
return sampleResponse;
}
}
Run Code Online (Sandbox Code Playgroud)
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>
}
}
Run Code Online (Sandbox Code Playgroud)
@InjectMocks 注释可用于将模拟字段自动注入测试对象。
在下面的示例中,@InjectMocks 用于将模拟 dataMap 注入到 dataLibrary 中。
@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"));
}
Run Code Online (Sandbox Code Playgroud)
很多人在这里对@Mock
vs给出了很好的解释@InjectMocks
。我喜欢它,但我认为我们的测试和应用程序应该以不需要使用@InjectMocks
.
进一步阅读示例的参考:https : //tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-annotation-to-autowire-fields/
归档时间: |
|
查看次数: |
231392 次 |
最近记录: |