JMock是一个使用模拟对象机制测试Java代码的开发包。模拟对象(Mock Object)可以取代真实对象的位置,用于测试一些与真实对象进行交互或依赖于真实对象的功能,模拟对象的背后目的就是创建一个轻量级的、可控制的对象来代替测试中需要的真实对象,模拟真实对象的行为和功能,方便我们的测试。JMock 就是这种机制的实现,使用 JMock 我们可以快速创建模拟对象,定义交互过程中的约束条件等,同时 JMock 也是易扩展的,你可以很方便添加自定义的需求。
(1)创建JMock上下文,例如:
Mockery context = new Mockery();
(2)根据接口创建模拟对象,例如:
final UserService userService = context.mock(UserService.class);
(3)在JMock上下文中创建我们的期望,即要依赖的服务。例如:
context.checking(new Expectations() {
{
// 当订单ID为100时,执行该期望
oneOf(userService).getUserInfo(100);
will(returnValue("orderId=100")); // 返回值
// 当订单ID为200时,执行该期望
oneOf(userService).getUserInfo(200);
will(returnValue("orderId=200")); // 返回值
}
});上面定义了两个期望,第一个当订单ID=100时被调用;第二个期望当订单ID=200时被调用,两个期望被调用时将返回值。
(4)使用模拟对象调用目标服务。
假如我们有一个订单服务和一个用户服务,但是这两个服务分别位于不同的模块中,同时这两个模块由两个不同的团队进行开发。其中,订单服务需要依赖用户服务,但是用户服务还没有开发完成;在实际开发中不可能去等待用户服务开发完成后再去开发订单服务。因此,我们需要使用 jmock 框架来模拟用户服务。下面将通过一个实例来讲解怎样使用 jmock 来模拟用户服务:
用户服务接口(UserService.java)定义如下:
/**
* 用户服务
* @author huangxin 2019/11/2
*/
public interface UserService {
/**
* 根据订单ID获取下订单的用户信息
* @param orderId 订单ID
* @return
*/
String getUserInfo(int orderId);
}订单服务(OrderService.java)定义如下:
/**
* 订单服务
* @author huangxin 2019/11/2
*/
public class OrderService {
private UserService userService; // 依赖用户服务
public void setUserService(UserService userService) {
this.userService = userService;
}
/**
* 根据订单ID查找订单
* @param orderId 订单ID
*/
public void findOrder(int orderId) {
System.out.println("OrderService - 开始查找订单 " + orderId);
// 获取用户信息
System.out.println(userService.getUserInfo(orderId));
System.out.println("OrderService - 完成订单查找 " + orderId + "\n\n");
}
}用户实体定义(User.java)如下:
/**
* 用户对象
* @author huangxin 2019/11/2
*/
public class User {
private int id;
private String name;
public User() {
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}测试客户端如下:
/**
* 客户端
* @author huangxin 2019/11/2
*/
public class Client {
public static void main(String[] args) {
// 建立一个 test 上下文对象
Mockery context = new Mockery();
// 生成一个mock对象
final UserService userService = context.mock(UserService.class);
// 设置期望
context.checking(new Expectations() {
{
// 当订单ID为100时,执行该期望
oneOf(userService).getUserInfo(100);
will(returnValue("orderId=100"));
// 当订单ID为200时,执行该期望
oneOf(userService).getUserInfo(200);
will(returnValue("orderId=200"));
}
});
// 创建订单服务对象
OrderService orderService = new OrderService();
orderService.setUserService(userService);
orderService.findOrder(100);
orderService.findOrder(200);
}
}跟多关于jmock的文章请阅读后续文章。