EasyMock简介和代码示例

关于EasyMock:

官网:easymock.org

注意:

3.0版本前,使用JDK的动态代理实现Mock对象创建,因此只能对接口进行mock,如果需要对类进行mock,需要使用扩展org.easymock.classextension.EasyMock
3.0后,可以针对接口&类进行mock
EasyMock范例(Service层代码单元测试):

1.工程中引入EasyMock包:

maven工程的话,pom包中添加依赖:


    org.easymock
    easymock
    3.4
    test

2.被测对象:

public class UserService{
    @Resource
    private UserDao userDao;
    
    private String getUserName(String userId)
    {
        User user = userDao.select(userId);
        
        if (null == user)
        {
            return "";
        }else {
            return "offline_" + user.getName();
        }
    }
}

其中UserService依赖UserDao接口的实现

3.测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:CommonUtils.xml")
public class UserServiceTest{

    private UserDao userDaoMock = null;
    
    private User userMock = null;

    @Resource
    private UserService userService;
    
    @Before
    public void setUp()
    {
        // 创建mock对象
        userDaoMock = EasyMock.createMock(UserDao.class);
        userMock = EasyMock.createMock(User.class);
        
        // mock对象注入被测对象
        Field userDaoField = userService.getDeclaredField("userDao");
        userDaoField.setAccessible(true);
        userDaoField.set(userService,userDaoMock);
    }
    
    
    @Test
    public void getUserName()
    {
        // 设置mock对象的期望值
        EasyMock.expect(userMock.getName()).andReturn("testName");
        EasyMock.expect(userDaoMock.select("1")).andReturn(userMock);
        
        // mock对象的replay
        EasyMock.replay(userMock);
        EasyMock.replay(userDaoMock);
        
        // 断言
        Assert.assertTrue(userService.getUserName("1").equals("offline_testName"));
        
        // 验证mock对象是否被调用
        EasyMock.verify(userMock);
        EasyMock.verify(userDaoMock);
    }
    
    @After
    public void tearDown() throws Exception {
        userDaoMock = null;
        userMock = null;
    }
}

根据官方文档,mock的todolist有:

  • Create the mock
  • Have it set to the tested class
  • Record what we expect the mock to do
  • Tell all mocks we are now doing the actual testing
  • Test
  • Make sure everything that was supposed to be called was called

我们范例中对应是:

1.使用EasyMock生成Mock对象:

userDaoMock = EasyMock.createMock(UserDao.class);
userMock = EasyMock.createMock(User.class);

2.Mock对象注入被测对象:
Field userDaoField = userService.getDeclaredField("userDao");
userDaoField.setAccessible(true);
userDaoField.set(userService,userDaoMock);

3.设定Mock对象的预期行为和输出:

EasyMock.expect(userMock.getName()).andReturn("testName");
EasyMock.expect(userDaoMock.select("1")).andReturn(userMock);

4.将Mock对象切换到Replay状态:

EasyMock.replay(userMock);
EasyMock.replay(userDaoMock);

5.调用Mock对象方法进行单元测试:
Assert.assertTrue(userService.getUserName("1").equals("offline_testName"));

6.确定mock对象有被调用:

EasyMock.verify(userMock);
EasyMock.verify(userDaoMock);

EasyMock进阶:
  • 使用IMocksControl管理多个mock对象
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:CommonUtils.xml")
public class UserServiceTest{

    private IMocksControl iMocksControl = null;

    private UserDao userDaoMock = null;
    
    private User userMock = null;

    @Resource
    private UserService userService;
    
    @Before
    public void setUp()
    {
        // 创建mock对象
        iMocksControl = EasyMock.createControl();
        userDaoMock = iMocksControl.createMock(UserDao.class);
        userMock = iMocksControl.createMock(User.class);
        
        // mock对象注入被测对象
        Field userDaoField = userService.getDeclaredField("userDao");
        userDaoField.setAccessible(true);
        userDaoField.set(userService,userDaoMock);
    }
    
    
    @Test
    public void getUserName()
    {
        // 设置mock对象的期望值
        EasyMock.expect(userMock.getName()).andReturn("testName");
        EasyMock.expect(userDaoMock.select("1")).andReturn(userMock);
        
        // mock对象的replay
        iMocksControl.replay();
        
        // 断言
        Assert.assertTrue(userService.getUserName("1").equals("offline_testName"));
        
        // 验证mock对象是否被调用
        iMocksControl.verify();
    }
    
    @After
    public void tearDown() throws Exception {
        userDaoMock = null;
        userMock = null;
    }
}

  • 使用注解
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:CommonUtils.xml")
public class UserServiceTest{

    @Rule
    private EasyMockRule mocks = new EasyMockRule(this);

    private IMocksControl iMocksControl = null;

    @Mock
    private UserDao userDaoMock = null;
    
    private User userMock = null;

    @TestSubject
    @Resource
    private UserService userService;
    ...
}

解析:

1.mock对象会被注入到userService对象中,@Mock是需要创建的mock对象,@TestSubject是被测类

2.如果没有下面这段代码设置Junit的rule,需要将测试类的Runner设置为@RunWith(EasyMockRunner.class),当你希望使用别的runner类,但是又需要EasyMock的注解时,使用Junit的rule进行扩展

@Rule
private EasyMockRule mocks = new EasyMockRule(this);

你可能感兴趣的:(EasyMock简介和代码示例)