使用带有junit的mockito
在与Mockito的本程序中,我们将使用另一个框架进行完整的测试,称为JUnit。
据JUNIT,
JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks.
使用Mockito,创建模拟对象非常简单。
它提供了许多简单的注释。
在内部,模拟只不过是实际类实例的代理。
以下是创建Mockito Junit示例的步骤。
第1步:创建一个简单的Java Maven项目。
maven依赖
第2步:将所需的依赖项添加到pom.xml
Maven依赖是Mockito开始最快的方法:
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.9.5</version> </dependency>
只是一个依赖性,不会带来任何其他库。
请参阅此处获取最新版本的库。
由于我们也将使用一些JUnit函数,我们还需要它是依赖。
让我们添加它,
<!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency>
最后,我们也将使用Assertj。
<dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.6.2</version> <scope>test</scope> </dependency>
pom.xml将如下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.igi.theitroad</groupId> <artifactId>MockitoJunitExample</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.9.5</version> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.6.2</version> <scope>test</scope> </dependency> </dependencies> </project>
Mockito和Junit.
轻松启动的最简单方法是通过显示一个例子。
第3步:我们将定义名为MathService的接口。
这是我们的接口:
package org.igi.theitroad.mockito; public interface MathService { long doubleLong(long num); long tripleLong(long num); long addition(long... nums); }
接下来,我们将增加其实现。
足够清楚,那些将是简单的数学实现:
package org.igi.theitroad.mockito; public class MathServiceImpl implements MathService { public long doubleLong(long num) { return 2 * num; } public long tripleLong(long num) { return 3 * num; } public long addition(long... nums) { int sum = 0; for (long a : nums) sum += a; return sum; } }
接下来做什么?
第4步:让我们专注于我们需要执行的步骤,以便开始使用Mockito Mocks:
- 用@runwith注释测试类(mockitojunitrunner.class)。
- 使用@Mock或者@spy注释注释测试字段以实例化模拟或者 Spy对象。
- 用@InjectMocks注释注释正在测试的系统。
让我们申请超过三个步骤来提供我们的测试演示。
package org.igi.theitroad.mockito; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class JUnitTest { @Mock MathService mathService; @InjectMocks MathServiceImpl mathServiceImpl = new MathServiceImpl(); @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test public void test_doubleLong_Pass() { long expected = 20; Mockito.when(mathService.doubleLong(Mockito.anyLong())).thenReturn(expected); long actual = mathService.doubleLong(Mockito.anyLong()); Assert.assertEquals(expected, actual); } @Test public void test_doubleLong_Inject() { long expected = 20; //this method is actually called long actual = mathServiceImpl.doubleLong(10); Assert.assertEquals(expected, actual); } }
现在,值得注意的是,当使用模拟时,不调用实际方法实现。
在我们写入的第二个测试用例中,实际上调用了该方法的实现。
当我们运行上面的测试时,我们将得到以下输出:
有时,测试案例类已经被@Runwith注释注释,Mockito的注释不会有任何影响。
为了纠正这个,我们必须调用MockitoAnnotations.InitMocks,如图所示,
@InjectMocks MeanCalculator systemUnderTest; @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test …
Mockito vs Junit.
JUnit是一个有助于编写和运行单元测试的框架。
Mockito(或者任何其他嘲弄工具)是我们专门用于有效地写某种测试的框架。
主要目的是执行单元测试以隔离我们想要从项目中的其他任何内容进行测试并测试其函数的程序。
为此,我们必须创建"测试双打",以便我们为"课堂级"的对象提供。
我们也可以创建所有这些"测试双打"自己,或者使用模拟框架,或者使用反射技术为我们生成一定类的对象。
有趣的是,有些人要求永远不要使用嘲笑框架,但没有他们,我们将是只是重新发明轮子,一个坏人。
换句话说:我们绝对可以使用JUnit而不使用嘲弄框架。
相反方向也是如此;但实际上,我们希望使用Mockito以外的其他任何内容,但只有很多好的原因。
@runwith(mockitojunitrunner.class)vs mockitoannotations.initmocks(这个)
使用Mockitojunitrunner而不是Junitrunner真的是可选的。
Bymockitojunitrunner提供的主要优势在使用@Mock方法创建模拟时,将在显式调用MockitoAnnotations.InitMocks(对象)。
但是,我们还可以使用此赛运行者获得Mockito框架的一些滥用报告,而可能在不使用它的情况下丢失。
可能在不使用Mockitojunitrunner的情况下捕获不正确的使用示例:
//Oops, thenReturn() part is missing: when(mock.get()); //Oops, verified method call is inside verify() where it should be on the outside: verify(mock.execute()); //Oops, missing method to verify: verify(mock);