高效单元测试——EasyMock技术与应用

目录

1.EasyMock 简介

2.EasyMock 实例

3.EasyMock 模型

3.1、record-replay-verify 模型

3.2、record

 3.3、replay

 3.4、verify

3.5、easymock部分功能说明

2. 记录mock对象期望的行为

4.EasyMock 应用

4.1、Easymock对AccountService进行测试

4.2、用Easymock对WebClient的测试

 ​编辑


1.EasyMock 简介

Mock 对象的弊端?

手动的构造 Mock 对象会给开发人员带来额外的编码量

为创建 Mock 对象而编写的代码很有可能引入错误

根据现有的接口或类动态生成 Mock 对象,能避免额外的编码工作,同时也降低了引入错误的可能。

EasyMock 是一套用于通过简单的方法对于给定的接口生成 Mock 对象的类库。

提供对接口的模拟,能够通过录制、回放、检查三步来完成大体的测试过程,可以验证方法的调用种类、次数、顺序,可以令 Mock 对象返回指定的值或抛出指定异常。

通过 EasyMock,可以方便的构造 Mock 对象从而使单元测试顺利进行

easymock的官网    https://easymock.org/

2.EasyMock 实例

public class User {
	private String id;
	private String name;
	private int age;
	public String getId() {return id;}
	public void setId(String id) {this.id = id;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}
	public int getAge() {return age;}
	public void setAge(int age) {this.age = age;}
	public User() {super();}
	public User(String id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
}
public interface UserService {
	User query(String userId);
}

 

public interface UserDao {
	User getById(String userId);
}
public class UserServiceImpl implements UserService {
	private UserDao userDao;
	public User query(String userId) {
		return userDao.getById(userId);
	}
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
}

定义两个interface:

  UserService 和 UserDao, 并给出了实现类UserServiceImpl 。 UserServiceImpl依赖到UserDao,通过setter方法可以注入一个UserDao实现。

使用mock object 技术测试UserServiceImpl

手动Mock的测试方法

class MockUserDao implements UserDao {
	private Map<String, User> users = new HashMap<String, User>();
	public void addUser(String userid, User user) {
		users.put(userid, user);
	}
	public User getById(String userId) {
		// TODO Auto-generated method stub
		return users.get(userId);
	}

完整测试方法

public class UserServiceImplTestWithMockObject {
	@Test
	public void testQuery() {
		User expectedUser = new User();
		expectedUser.setId("1001");
		expectedUser.setAge(30);
		expectedUser.setName("user-1001");
		
		MockUserDao mud = new MockUserDao();
		mud.addUser("1001", expectedUser);
 
		UserServiceImpl service = new UserServiceImpl();
		service.setUserDao(mud);
		User user = service.query("1001");
		assertNotNull(user);
		assertEquals("1001", user.getId());
		assertEquals(30, user.getAge());
		assertEquals("user-1001", user.getName());
	}
}

 如果使用EasyMock技术,如何实现,带来多大的方便???

 

 

3.EasyMock 模型

3.1、record-replay-verify 模型

record-replay-verify 模型容许记录mock对象上的操作然后重演并验证这些操作。

是目前mock框架领域最常见的模型

几乎所有的mock框架都是用这个模型

3.2、record

        

UserDao userDao = EasyMock.createMock(UserDao.class);
EasyMock.expect(userDao.getById("1001")).andReturn(expectedUser);
创建mock对象,并期望这个mock对象的方法被调用,同时给出希望这个方法返回的结果。
这就是"记录mock对象上的操作", 同时也会看到" expect "这个关键字。
在record阶段,需要给出的是对mock对象的一系列 期望 :若干个mock对象被调用,依从给定的 参数,顺序,次数 等,并返回预设好的结果(返回值或者异常).

 3.3、replay

EasyMock.replay(mockUserDao);
		UserServiceImpl service = new UserServiceImpl();
		service.setUserDao(mockUserDao);
		User user = service.query("1001");    
replay 阶段,主要测试对象被创建,前面在 record 阶段创建的相关依赖被关联到主要测试对象,然后执行被测试的方法,以模拟真实运行环境下主要测试对象的行为。

 

在测试方法执行过程中,主要测试对象的内部代码被执行,同时和相关的依赖进行交互:

以一定的参数调用依赖的方法,获取并处理返回。
期待这个过程如在 record 阶段设想的交互场景一致,即期望在 replay 阶段所有在 record 阶段记录的行为都将被 完整而准确的重新演绎一遍 ,从而到达验证主要测试对象行为的目的。

 3.4、verify

nverify阶段,将验证测试的结果交互行为

assertNotNull(user);
assertEquals("1001", user.getId());
assertEquals(30, user.getAge());
assertEquals("user-1001", user.getName());

EasyMock.verify(userDao);

验证结果,即主要测试对象的测试方法返回的结果(对于异常测试场景则是抛出的异常)是否如预期,通常这个验证过程需要自行编码实现

                        EasyMock.verify(userDao);

                       验证交互行为,典型如依赖是否被调用,调用的参数,顺序和次数,这部分的验证过程通常是由mock框架来自动完成。

3.5、easymock部分功能说明

1. 创建mock对象

UserDao mockUserDao = Easymock.createMock(UserDao.class);

2. 记录mock对象期望的行为

Easymock.expect(mockUserDao.getById("1001")).andReturn(expectedUser);

这里记录了mock对象的行为:getById()方法被调用,调用次数为1

(easymock之中如果没有明确指出调用次数,默认为1),参数为"1001",expectedUser将作为返回值

3. 进入replay阶段

 Easymock.replay(mockUserDao);

4. 对mock对象执行验证

Easymock.verify(mockUserDao);

5. 指定期望的调用次数

Easymock.expect(mockUserDao.getById("1001")).andReturn(expectedUser).times(3);

6. 指定抛出期望的异常

Easymock.expect(mockUserDao.getById("1001")).andThrow(new RuntimeException("no user exist"));

7. 记录void 方法的行为:

如果mock对象的方法是void,则需要使用expectLastCall():

mockUserDao.someVoidMethod();

Easymock.expectLastCall();

和Easymock.expect(***)一样,同样支持指定调用次数,抛出异常等:

Easymock.expectLastCall().times(3);

Easymock.expectLastCall().andThrow(new RuntimeException("some error"));

8. 灵活的参数匹配

Easymock.expect(mockUserDao.getById(Easymock.isA(String.class))).andReturn(expectedUser);

类似的还有anyInt(),anyObject(), isNull() , same(), startsWith()等诸多实现。

4.EasyMock 应用

4.1、Easymock对AccountService进行测试

4.2、用Easymock对WebClient的测试

 

 

 

 

 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Eclipse是一款常用的集成开发环境(IDE),用于开发Java应用程序。在Eclipse中,我们可以通过一些插件和工具来方便地生成和运行单元测试。 首先,在Eclipse中,我们可以使用JUnit插件来生成和管理单元测试。JUnit是一个流行的Java单元测试框架,它提供了一系列注解和断言方法,能够方便地编写和执行单元测试。 要生成单元测试,我们首先需要创建一个Java类或方法,然后右键点击该类或方法,在弹出菜单中选择“Coverage As”->“JUnit Test”。这将会生成一个测试类,并自动导入JUnit的相关库并创建相应的测试方法。 生成的测试方法会自动使用JUnit的注解进行标记,例如@Test表示该方法是一个单元测试方法。在测试方法中,我们可以使用各种断言方法,如assertEquals、assertTrue等来验证代码的正确性。 在生成单元测试后,我们可以通过运行JUnit测试来执行测试代码。只需要右键点击测试类,选择“Run As”->“JUnit Test”,或者使用Eclipse的快捷键Ctrl + F11来运行测试。 运行单元测试后,JUnit将显示测试通过和测试失败的结果,并提供详细的错误信息。我们可以通过查看测试结果来了解代码是否按照预期运行,并且快速定位和修复错误。 此外,Eclipse还提供了一些其他工具和插件来辅助单元测试的生成和执行,如Mockito、EasyMock等。这些工具可以帮助我们模拟和控制一些外部依赖,使得单元测试更加简单和高效。 总之,通过Eclipse中的JUnit插件和其他辅助工具,我们可以方便地生成和执行单元测试,以确保我们的Java代码质量和正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pig Pig Cat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值