mockito教程
Mockito is a java based mocking framework, used in conjunction with other testing frameworks such as JUnit and TestNG.
Mockito是基于Java的模拟框架,可与其他测试框架(例如JUnit和TestNG)结合使用。
It internally uses Java Reflection API and allows to create objects of a service. A mock object returns a dummy data and avoids external dependencies. It simplifies the development of tests by mocking external dependencies and apply the mocks into the code under test.
它在内部使用Java Reflection API,并允许创建服务对象。 模拟对象返回伪数据,并避免外部依赖关系。 它通过模拟外部依赖关系简化了测试的开发,并将模拟应用于测试中的代码。
For the Mockito tutorial, we will use JUnit 5 and create some services to mock.
对于Mockito教程,我们将使用JUnit 5并创建一些模拟服务。
To implement Mockito based test cases in a project, add the following dependency to the pom.xml file of the project:
要在项目中实现基于Mockito的测试用例,请将以下依赖项添加到项目的pom.xml文件中:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.19.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.19.0</version>
<scope>test</scope>
</dependency>
Note that mockito-junit-jupiter
is required for JUnit 5, if you are using any other testing framework such as JUnit 4 or TestNG then you remove this dependency and include only mockito-core
dependency.
请注意,如果您使用的是JUnit 4或TestNG之类的任何其他测试框架,那么JUnit 5便需要mockito-junit-jupiter
,然后删除此依赖项,并仅包含mockito-core
依赖项。
The Mockito framework allows us to create mock objects using either @Mock
annotation or mock()
static method.
Mockito框架允许我们使用@Mock
批注或mock()
静态方法创建模拟对象。
The below example shows the usage of mock() method:
下面的示例演示了mock()方法的用法:
package com.journaldev.mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import com.journaldev.AddService;
import com.journaldev.CalcService;
public class CalcService1Test {
@Test
void testCalc() {
System.out.println("**--- Test testCalc executed ---**");
AddService addService;
CalcService calcService;
addService = Mockito.mock(AddService.class);
calcService = new CalcService(addService);
int num1 = 11;
int num2 = 12;
int expected = 23;
when(addService.add(num1, num2)).thenReturn(expected);
int actual = calcService.calc(num1, num2);
assertEquals(expected, actual);
}
}
In the above example, we are testing CalcService
. Mockito.mock() method is used to create a mock object of AddService
class.
在上面的示例中,我们正在测试CalcService
。 Mockito.mock()方法用于创建AddService
类的模拟对象。
The below example shows the usage of @Mock annotation.
下面的示例显示@Mock注释的用法。
package com.journaldev.mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import com.journaldev.AddService;
import com.journaldev.CalcService;
public class CalcService2Test {
CalcService calcService;
@Mock
AddService addService;
@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testCalc() {
System.out.println("**--- Test testCalc executed ---**");
calcService = new CalcService(addService);
int num1 = 11;
int num2 = 12;
int expected = 23;
when(addService.add(num1, num2)).thenReturn(expected);
int actual = calcService.calc(num1, num2);
assertEquals(expected, actual);
}
}
Note that we need to call MockitoAnnotations.initMocks(this);
to initialize objects annotated with @Mock, @Spy, @Captor, or @InjectMocks.
注意,我们需要调用MockitoAnnotations.initMocks(this);
初始化以@ Mock,@ Spy,@ Captor或@InjectMocks注释的对象。
To add a behavior to the mocked class when()
and thenReturn()
functions are used. It means that when the mock object (addService) is called for add method with (num1, num2) parameters, then it returns the value stored in the expected variable.
要将行为添加到thenReturn()
类中,使用when()
和thenReturn()
函数。 这意味着,当使用(num1,num2)参数的添加方法调用模拟对象(addService)时,它将返回存储在预期变量中的值。
Our CalcService class looks like below:
我们的CalcService类如下所示:
public class CalcService {
private AddService addService;
public CalcService(AddService addService) {
this.addService = addService;
}
public int calc(int num1, int num2) {
System.out.println("**--- CalcService calc executed ---**");
return addService.add(num1, num2);
}
}
The CalcService has a dependency on AddService class. It uses the AddService class’s add method to perform its operation.
CalcService依赖于AddService类。 它使用AddService类的add方法执行其操作。
Since we wanted to do unit testing of CalcService class only, we have to mock the AddService instance. The AddService looks like below:
由于我们只想对CalcService类进行单元测试,因此我们必须模拟AddService实例。 AddService如下所示:
public interface AddService {
public int add(int num1, int num2);
}
public class AddServiceImpl implements AddService {
@Override
public int add(int num1, int num2) {
System.out.println("**--- AddServiceImpl add executed ---**");
return num1 + num2;
}
}
Mockito framework keeps track of all the method calls and their parameters to the mock object. Mockito verify()
method on the mock object verifies that a method is called with certain parameters. We can also specify the number of invocation logic, such as the exact number of times, at least specified number of times, less than the specified number of times, etc. We can use VerificationModeFactory
for number of invocation times logic.
Mockito框架跟踪对模拟对象的所有方法调用及其参数。 模拟对象上的Mockito verify()
方法验证是否使用某些参数调用了该方法。 我们还可以指定调用逻辑的数量,例如确切的次数,至少指定的次数,小于指定的次数等。我们可以将VerificationModeFactory
用于调用次数的逻辑。
Mockito verify() method checks that a method is called with the right parameters. It does not check the result of a method call like assert method. The below example demonstrates the usage of verify() method:
Mockito verify()方法检查是否使用正确的参数调用了一个方法。 它不会检查类似assert方法的方法调用的结果。 下面的示例演示了verify()方法的用法:
package com.journaldev.mockito;
import static org.mockito.Mockito.verify;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.mockito.internal.verification.VerificationModeFactory;
public class VerifyInteractionTest {
@Test
public void testMethod() {
@SuppressWarnings("unchecked")
List<String> mockedList = Mockito.mock(List.class);
mockedList.add("first-element");
mockedList.add("second-element");
mockedList.add("third-element");
mockedList.add("third-element");
mockedList.clear();
verify(mockedList).add("first-element");
verify(mockedList).add("second-element");
verify(mockedList, VerificationModeFactory.times(2)).add("third-element");
verify(mockedList).clear();
}
}
Using when() – thenReturn() function, we can stub a concrete/implementation class and also a single element of a collection. The non-stubbed elements will contains null in them.
使用when()– thenReturn()函数,我们可以对具体/实现类以及集合的单个元素进行存根。 非存根元素将在其中包含null。
package com.journaldev.mockito;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MockSingleElementTest {
@SuppressWarnings("unchecked")
@Test
public void testMethod() {
ArrayList
mockedList = mock(ArrayList.class);
when(mockedList.get(0)).thenReturn("first-element");
System.out.println(mockedList.get(0));
assertEquals("first-element", mockedList.get(0));
// "null" gets printed as get(1) is not stubbed
System.out.println(mockedList.get(1));
}
}
When you call the method of a spied object, the real method will be called, unless a predefined behavior was defined. Using spy we can define behavior by using when() – theReturn() functions or can invoke real implementation.
当调用间谍对象的方法时,除非定义了预定义的行为,否则将调用real方法。 使用间谍,我们可以通过when()-theReturn()函数定义行为,或者可以调用实际实现。
package com.journaldev.mockito;
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 MockitoSpyTest {
@Test
public void testMethod() {
List<String> list = new ArrayList<>();
List<String> listSpy = spy(list);
listSpy.add("first-element");
System.out.println(listSpy.get(0));
assertEquals("first-element", listSpy.get(0));
when(listSpy.get(0)).thenReturn("second-element");
System.out.println(listSpy.get(0));
assertEquals("second-element", listSpy.get(0));
}
}
Mockito is a popular mocking framework for Java unit testing. We can easily mock dependencies using Mockito. Mockito coding style is fluent and similar to JUnit and TestNG frameworks, so its learning curve is very small.
Mockito是用于Java单元测试的流行模拟框架。 我们可以使用Mockito轻松模拟依赖项。 Mockito的编码风格流畅并且类似于JUnit和TestNG框架,因此其学习曲线很小。
mockito教程