本文概述
- 1.存根示例
- 2.模拟示例
- 3.模拟List类的示例
- 4.列表的多个返回值的示例
- 5.模拟List.get()方法的示例
- 6. verify()方法的示例
- 7. Mockito spy()的示例
JUnit是Java程序员用于创建测试用例的测试框架之一。与Mockito一样, JUnit也是一个开放源代码测试框架。要深入了解JUnit框架的概念, 请单击给定的链接https://www.srcmini.com/junit-tutorial。
1.存根示例 在此示例中, 我们将使用存根测试一个简单的模块。以下是创建测试示例的步骤:
目录结构
文章图片
步骤1:添加应用程序所需的Maven依赖项。依赖关系始终添加在应用程序的pom.xml文件中。在此示例中, 你需要添加两个依赖项:
- JUnit依赖
- Mockito依赖
<
dependency>
<
groupId>
junit<
/groupId>
<
artifactId>
junit<
/artifactId>
<
version>
4.13-rc-1<
/version>
<
scope>
test<
/scope>
<
/dependency>
<
dependency>
<
groupId>
org.mockito<
/groupId>
<
artifactId>
mockito-all<
/artifactId>
<
version>
2.0.1-beta<
/version>
<
scope>
test<
/scope>
<
/dependency>
步骤2:创建一个名为ToDoService.java的接口, 其中包含一个未实现的方法, 如下所示。
ToDoService.java
import java.util.List;
public interface ToDoService { public List<
String>
getTodos(String user);
}
步骤3:创建一个名为ToDoBusiness.java的Java类, 其中包含一个参数化的构造函数和一个方法, 如下所示。
ToDoBusiness.java
import java.util.ArrayList;
import java.util.List;
// ToDoBusiness is a SUT (system under test) // ToDoService is a Dependency (as ToDoBusiness is dependent on it)public class ToDoBusiness { public ToDoService doService;
public ToDoBusiness(ToDoService doService) {this.doService = doService;
} public List<
String>
getTodosforSpring(String user) {List<
String>
retrievedtodos = new ArrayList<
String>
();
List<
String>
todos = doService.getTodos(user);
for(String todo :todos) {if(todo.contains("Spring")) {retrievedtodos.add(todo);
}}return retrievedtodos;
} }
步骤4:在测试的源文件夹(src / test / java)中创建一个名为ToDoServiceStub.java的存根类, 以进行测试。
ToDoServiceStub.java
import java.util.Arrays;
import java.util.List;
public class ToDoServiceStub implements ToDoService{ public List<
String>
getTodos(String user) { return Arrays.asList(" Use Core Java ", " Use Spring Core ", " Use Hibernate ", " Use Spring MVC ");
} }
步骤5:创建另一个名为ToDoBusinessStub.java的存根, 如下所示。
ToDoBusinessStub.java
import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
public class ToDoBusinessStub { @Test public void test() {ToDoService doServiceStub = new ToDoServiceStub();
ToDoBusiness business = new ToDoBusiness(doServiceStub);
List<
String>
retrievedtodos = business.getTodosforSpring(" Dummy ");
assertEquals(2, retrievedtodos.size());
System.out.println(" Stub is working correctly...!!");
} }
输出如下
以下输出显示存根工作正常。
文章图片
文章图片
存根的缺点
在上面的示例中, ToDoBusinessStub依赖于ToDoService接口, 因此我们创建了一个名为ToDoServiceStub的存根, 该存根返回虚拟值。 ToDoServiceStub什么都不是, 而是真正的Java类。使用存根存在许多维护问题。例如, 如果要向ToDoService接口添加新方法或从ToDoService接口删除现有方法, 则需要跟踪与此接口相关的存根。存根的另一个问题是使代码更加复杂的动态条件。
存根在简单的项目和场景中很有用, 但是在复杂的场景中, 我们需要比存根更动态的东西。为了克服这些弊端, 使用了模拟而不是存根。
在上面的示例中, 我们还没有使用Mockito框架, 因为我们创建了一个简单的测试模块。现在, 我们将创建一个模拟示例。在创建模拟示例之前, 我们应该了解示例中将要使用的一些重要概念和方法。
2.模拟示例 在这里, 我们将创建一个模拟对象的示例。以下步骤用于创建将Mockito与JUnit一起使用的测试示例。
步骤1:创建一个名为ToDoService的接口, 其中包含一个未实现的方法。
ToDoService.java
import java.util.List;
public interface ToDoService { public List<
String>
getTodos(String user);
}
步骤2:现在, 为ToDoService接口创建一个名为ToDoBusiness的实现类。
ToDoBusiness.java
import java.util.ArrayList;
import java.util.List;
// ToDoBusiness is a SUT (system under test) // ToDoService is a Dependency (as ToDoBusiness is dependent on it)public class ToDoBusiness { public ToDoService doService;
public ToDoBusiness(ToDoService doService) {this.doService = doService;
} public List<
String>
getTodosforHibernate(String user) {List<
String>
hibernatelist = new ArrayList<
String>
();
List<
String>
Combinedlist = doService.getTodos(user);
for(String todo: Combinedlist) {if(todo.contains("Hibernate")) {hibernatelist.add(todo);
}}return hibernatelist;
} }
步骤3:创建一个名为ToDoBusinessMock的JUnit测试用例, 以进行单元测试。
ToDoBusinessMock.java
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
public class ToDoBusinessMock { @Test public void testusing_Mocks() {ToDoService doService = mock(ToDoService.class);
List<
String>
combinedlist = Arrays.asList(" Use Core Java ", " Use Spring Core ", " Use w3eHibernate ", " Use Spring MVC ");
when(doService.getTodos("dummy")).thenReturn(combinedlist);
ToDoBusiness business = new ToDoBusiness(doService);
List<
String>
alltd = business.getTodosforHibernate("dummy");
System.out.println(alltd);
assertEquals(1, alltd.size());
} }
输出如下
以下输出显示测试已成功运行。它还显示该对象在列表中可用, 即” 使用休眠” 。
文章图片
3.模拟List类的示例 在这里, 我们将创建一个模拟List类(java.util.List)的示例。
步骤1:创建一个名为TestList的模拟测试类以测试List类。
TestList.java
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
import java.util.List;
import org.junit.Test;
import org.mockito.Mock;
public class TestList { @Test public void testList_ReturnsSingle_value() {List mocklist = mock(List.class);
when(mocklist.size()).thenReturn(1);
assertEquals(1, mocklist.size());
assertEquals(1, mocklist.size());
System.out.println( mocklist.size());
System.out.println(mocklist);
} }
输出如下
【Eclipse IDE中Mockito和JUnit的示例】以下输出显示测试成功运行, 并且列表中有一项可用。它还显示了对象的值。
文章图片
4.列表的多个返回值的示例 在这里, 我们将创建一个模拟具有多个返回值的List类(java.util.List)的示例。在上一个示例中, 该列表仅返回一个对象(因为它仅包含一个对象), 而在下一个示例中, 该列表返回了多个值(由于它包含三个项目)。
步骤1:创建一个名为TestList的JUnit测试用例, 以测试List类。
TestList.java
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
import java.util.List;
import org.junit.Test;
import org.mockito.Mock;
public class TestList { @Test public void testList_Returns_MultipleValues() {List mocklist = mock(List.class);
when(mocklist.size()).thenReturn(1).thenReturn(2).thenReturn(3);
assertEquals(1, mocklist.size());
assertEquals(2, mocklist.size());
assertEquals(3, mocklist.size());
System.out.println(mocklist.size());
System.out.println(mocklist);
} }
输出如下
以下输出显示该测试已成功运行, 并且返回了List的多个返回值。
文章图片
5.模拟List.get()方法的示例 在此示例中, 我们将模拟List.get()方法。要使用get()方法, 我们需要在其中传递一个值(数字), 如示例所示。
步骤1:创建一个名为TestList的测试类来模拟List.get()方法。
TestList.java
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.List;
import org.junit.Test;
public class TestList {@Test public void testList_get() {List mocklist = mock(List.class);
when(mocklist.get(0)).thenReturn("Mockito");
assertEquals("Mockito", mocklist.get(0));
System.out.println(mocklist.get(0));
} }
输出如下
以下输出显示当列表的索引值为0时测试成功运行, 并且返回给定的String, 即Mockito。
文章图片
但是, 如果我们要检查assertEquals(” Mockito” , mocklist.get(1)), 则测试将失败并引发错误, 如下所示。
文章图片
当调用mocklist.get()方法时, 它将始终返回Mockito。为了避免这种情况, 参数匹配器应运而生。借助参数匹配器, 我们可以获取任何整数的值, 无论该值是否存根。
6. verify()方法的示例 在这里, 我们将创建一个使用Mockito的verify()方法进行测试的示例。
步骤1:创建一个名为ToDoService的接口, 其中包含两个未实现的方法。
ToDoService.java
import java.util.List;
public interface ToDoService { public List<
String>
getTodos(String user);
public void deleteTodos(String doString);
}
步骤2:创建名为ToDoBusiness的实现类, 并删除与” 休眠” 无关的todo(List的对象)。
ToDoBusiness.java
import java.util.ArrayList;
import java.util.List;
// ToDoBusiness is a SUT (system under test) // ToDoService is a Dependency (as ToDoBusiness is dependent on it)public class ToDoBusiness { public ToDoService doService;
public ToDoBusiness(ToDoService doService) {this.doService = doService;
}public void deleteTodosNotRelatedToHibernate(String user) {List<
String>
Combinedlist = doService.getTodos(user);
for(String todos:Combinedlist) {if(!todos.contains("Hibernate")) {doService.deleteTodos(todos);
}} } }
步骤3:创建一个名为ToDoBusinessMock的模拟类, 并验证是否调用了指定的方法(deleteTodosNotRelatedToHibernate())。
ToDoBusinessMock.java
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
public class ToDoBusinessMock { @Test public void deleteTodosusing_BDD() {//GivenToDoService todoService = mock(ToDoService.class);
List<
String>
combinedlist = Arrays.asList("Use Hibernate Java", "Use Hibernate Core", "Use Hibernate", "Use Spring MVC");
given(todoService.getTodos("dummy")).willReturn(combinedlist);
ToDoBusiness business = new ToDoBusiness(todoService);
//Whenbusiness.deleteTodosNotRelatedToHibernate("dummy");
//Thenverify(todoService).deleteTodos("Use Spring MVC");
} }
输出如下
以下输出显示测试已成功运行。因此, 表明所有方法都得到了很好的验证。
文章图片
如果你希望某个项目永远不被调用或删除, 则可以使用一个方法never()进行操作, 例如:
verify(todoService, never()).deleteTodos("Use Hibernate Java");
verify(todoService, never()).deleteTodos("Use Hibernate");
通过使用times()方法, 可以指定特定方法的调用次数。例如:
verify(todoService, times(1)).deleteTodos("Use Spring MVC");
同样, 你可以使用其他Mockito方法, 例如atLeastOnce(), atLeast()和atMost()和verify()。
7. Mockito spy()的示例 为了测试目的, 我们创建一个名为SpyTest的测试类。
SpyTest.java
import static org.junit.Assert.*;
import static org.mockito.Mockito.spy;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class SpyTest { @Test public void test() {List spyArrayList = spy(ArrayList.class);
assertEquals(0, spyArrayList.size());
// adding an item in the listspyArrayList.add("Mockito");
assertEquals(1, spyArrayList.size());
} }
在上面的代码中, 我们创建了ArrayList类的间谍并检查了其大小。列表的大小为零, 表示列表为空。检查列表大小后, 我们在列表中添加了一个项目(” Mockito” )。现在, 由于我们讨论过间谍会创建真实对象的部分模拟, 因此大小增加了一个。
输出如下
文章图片
spy()方法让实际动作继续发生, 除了他们想改变行为的东西。这意味着spy()方法允许我们跟踪真实对象发生的情况, 并允许我们覆盖特定行为。
推荐阅读
- Android Studio删除依赖
- Mockito注解用法示例
- Mockito框架教程入门介绍
- 模拟与存根与监控
- Godot中的动画设计实例
- Mockito的方法
- Godot启动屏幕设计实例图解(2)
- Godot中的SceneTree
- Godot启动屏幕设计实例图解