mockito单元测试示例_Mockito模拟示例
mockito单元测试示例Mockito mocking framework provides different ways to mock a class. Let’s look at different methods through which we can mock a class and stub its behaviors. Mockito模拟框架提供了模拟类的不同方法。 让我们看一下
mockito单元测试示例
Mockito mocking framework provides different ways to mock a class. Let’s look at different methods through which we can mock a class and stub its behaviors.
Mockito模拟框架提供了模拟类的不同方法。 让我们看一下可以模拟类并存根其行为的不同方法。
Mockito模拟方法 (Mockito mock method)
We can use Mockito class mock() method to create a mock object of a given class or interface. This is the simplest way to mock an object.
我们可以使用Mockito类的mock()方法创建给定类或接口的模拟对象。 这是模拟对象的最简单方法。
package com.journaldev.mockito.mock;
import java.util.List;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class MockitoMockMethodExample {
@SuppressWarnings("unchecked")
@Test
public void test() {
// using Mockito.mock() method
List<String> mockList = mock(List.class);
when(mockList.size()).thenReturn(5);
assertTrue(mockList.size()==5);
}
}
We are using JUnit 5 to write test cases in conjunction with Mockito to mock objects.
我们使用JUnit 5与Mockito一起编写测试用例来模拟对象。
Mockito @模拟注解 (Mockito @Mock Annotation)
We can mock an object using @Mock annotation too. It’s useful when we want to use the mocked object at multiple places because we avoid calling mock() method multiple times. The code becomes more readable and we can specify mock object name that will be useful in case of errors.
我们也可以使用@Mock注释来模拟对象。 当我们想在多个地方使用模拟对象时,这很有用,因为我们避免了多次调用mock()方法。 代码变得更具可读性,我们可以指定模拟对象名称,以防出现错误。
When using @Mock annotation, we have to make sure that we call MockitoAnnotations.initMocks(this)
to initialize the mocked object. We can do this in testing framework setup methods that are executed before the tests.
使用@Mock批注时,我们必须确保调用MockitoAnnotations.initMocks(this)
来初始化MockitoAnnotations.initMocks(this)
对象。 我们可以在测试之前执行的测试框架设置方法中执行此操作。
package com.journaldev.mockito.mock;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class MockitoMockAnnotationExample {
@Mock
List<String> mockList;
@BeforeEach
public void setup() {
//if we don't call below, we will get NullPointerException
MockitoAnnotations.initMocks(this);
}
@SuppressWarnings("unchecked")
@Test
public void test() {
when(mockList.get(0)).thenReturn("JournalDev");
assertEquals("JournalDev", mockList.get(0));
}
}
Mockito @InjectMocks批注 (Mockito @InjectMocks Annotation)
When we want to inject a mocked object into another mocked object, we can use @InjectMocks annotation. @InjectMock creates the mock object of the class and injects the mocks that are marked with the annotations @Mock into it.
当我们要将一个模拟对象注入另一个模拟对象时,可以使用@InjectMocks批注。 @InjectMock创建类的模拟对象,并将带有注解@Mock的模拟注入到该类中。
package com.journaldev.mockito.mock;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class MockitoInjectMockAnnotationExample {
@Mock
List<String> mockList;
//@InjectMock creates an instance of the class and
//injects the mocks that are marked with the annotations @Mock into it.
@InjectMocks
Fruits mockFruits;
@BeforeEach
public void setup() {
//if we don't call below, we will get NullPointerException
MockitoAnnotations.initMocks(this);
}
@SuppressWarnings("unchecked")
@Test
public void test() {
when(mockList.get(0)).thenReturn("Apple");
when(mockList.size()).thenReturn(1);
assertEquals("Apple", mockList.get(0));
assertEquals(1, mockList.size());
//mockFruits names is using mockList, below asserts confirm it
assertEquals("Apple", mockFruits.getNames().get(0));
assertEquals(1, mockFruits.getNames().size());
mockList.add(1, "Mango");
//below will print null because mockList.get(1) is not stubbed
System.out.println(mockList.get(1));
}
}
class Fruits{
private List<String> names;
public List<String> getNames() {
return names;
}
public void setNames(List<String> names) {
this.names = names;
}
}
Mockito spy()用于部分模拟 (Mockito spy() for partial mocking)
If we want to mock only specific behaviors and call the real methods for unstubbed behaviors, then we can create a spy object using Mockito spy() method.
如果我们只想模拟特定的行为,并为未受干扰的行为调用真实的方法,则可以使用Mockito spy()方法创建一个间谍对象。
package com.journaldev.mockito.mock;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
public class MockitoSpyMethodExample {
@Test
public void test() {
List<String> list = new ArrayList<>();
List<String> spyOnList = spy(list);
when(spyOnList.size()).thenReturn(10);
assertEquals(10, spyOnList.size());
//calling real methods since below methods are not stubbed
spyOnList.add("Pankaj");
spyOnList.add("Meghna");
assertEquals("Pankaj", spyOnList.get(0));
assertEquals("Meghna", spyOnList.get(1));
}
}
Mockito @间谍注释 (Mockito @Spy Annotation)
We can use @Spy annotation to spy on an object. Let’s look at a simple example.
我们可以使用@Spy注释来监视对象。 让我们看一个简单的例子。
package com.journaldev.mockito.mock;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
public class MockitoSpyAnnotationExample {
@Spy
Utils mockUtils;
@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void test() {
when(mockUtils.process(1, 1)).thenReturn(5);
//mocked method
assertEquals(5, mockUtils.process(1, 1));
//real method called since it's not stubbed
assertEquals(20, mockUtils.process(19, 1));
}
}
class Utils{
public int process(int x, int y) {
System.out.println("Input Params = "+x+","+y);
return x+y;
}
}
Note that the @Spy annotation tries to call the no-args constructor to initialized the mocked object. If your class doesn’t have it then you will get the following error.
请注意,@ Spy注释会尝试调用no-args 构造函数以初始化模拟对象。 如果您的班级没有它,那么您将收到以下错误。
org.mockito.exceptions.base.MockitoException: Unable to initialize @Spy annotated field 'mockUtils'.
Please ensure that the type 'Utils' has a no-arg constructor.
at com.journaldev.mockito.mock.MockitoSpyAnnotationExample.setup(MockitoSpyAnnotationExample.java:18)
Also, note that Mockito cannot instantiate inner classes, local classes, abstract classes, and interfaces. So it’s always a good idea to provide an instance to spy on. Otherwise real methods might not get called and silently ignored.
另外,请注意,Mockito无法实例化内部类,局部类,抽象类和接口。 因此,提供一个实例进行监视始终是一个好主意。 否则,实际的方法可能不会被调用并被静默忽略。
For example, if you specify a spy object as below:
例如,如果您指定一个间谍对象,如下所示:
@Spy
List<String> spyList;
You will notice that when you call add()
or get()
methods, real methods are not getting called. If you specify the spy object like below, then everything will work fine.
您会注意到,当您调用add()
或get()
方法时,不会调用实际方法。 如果您指定如下所示的间谍对象,那么一切都会正常进行。
@Spy
List<String> spyList = new ArrayList<>();
摘要 (Summary)
Mockito mocking framework allows us to create mock object easily through different methods and annotations. We can also inject a mock object into another mock object, this is a very useful feature.
Mockito模拟框架允许我们通过不同的方法和注释轻松创建模拟对象。 我们还可以将一个模拟对象注入另一个模拟对象,这是一个非常有用的功能。
mockito单元测试示例
更多推荐
所有评论(0)