Junit--EasyMock测试servlet

用EasyMock做单元测试

import com.wang.service.service.Service;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import static org.junit.Assert.assertNotNull;

/**
 * UserRegister Tester.
 *
 * @author <Authors name>
 * @version 1.0
 * @since <pre>六月 16, 2018</pre>
 */
public class UserRegisterTest {


    private HttpServletRequest request;
    private HttpServletResponse response;
    private HttpSession session;

    @Before
    public void before() throws Exception {
        // 创建request和response的Mock
        request = EasyMock.createMock(HttpServletRequest.class);
        response = EasyMock.createMock(HttpServletResponse.class);
        session = EasyMock.createMock(HttpSession.class);
    }

    @After
    public void after() throws Exception {
    }

    /**
     * Method: newService()
     */
    @Test
    public void testNewService() throws Exception {
//TODO: Test goes here... 
    }

    /**
     * Method: execute(HttpServletRequest req, HttpServletResponse resp)
     */
    @Test
    public void testExecute() throws Exception {
        Service service = UserRegister.newService();

        EasyMock.expect(request.getParameter("rUserName")).andReturn("UserRegisterTest").once();    //期望使用参数
        EasyMock.expect(request.getParameter("rUserPassword1")).andReturn("testtest").times(1);  //期望调用的次数

        EasyMock.replay(request);   //保存期望结果

        ServiceResult result = service.execute(request, response);

        assertNotNull(result.getPage());
        assertNotNull(result.getErrormsg());
    }

} 

EasyMock
引入到工程

使用如下方式在Maven中添加EasyMock的依赖:

<dependency>  
    <groupId>org.easymock</groupId>  
    <artifactId>easymock</artifactId>  
    <version>3.4</version>  
    <scope>test</scope>  
</dependency>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
基本用法

先“录制”后使用: 
- 先创建一个mock对象: EasyMock.createMock 
- 录制对象的行为(打桩) 
- 声明录制完成:EasyMock.replay

UserDao mock  = EasyMock.createMock(UserDao.class);//创建Mock对象  
            EasyMock.expect(mock.getById("1001")).andReturn(expectedUser);//录制Mock对象预期行为  
EasyMock.expect(mock.getById("1002")).andThrow(new RuntimeException());

EasyMock.replay(mock);//重放Mock对象,测试时以录制的对象预期行为代替真实对象的行为 
  • 1
  • 2
  • 3
  • 4
  • 5
高级用法
参数匹配
  • 匹配特定参数
EasyMock.expect(mock.getById("1001")).andThrow(new RuntimeException());  
  • 1
  • 匹配参数类型
EasyMock.expect(mock.getById(EasyMock.isA(String.class))).andReturn(exceptedUser).times(3);
  • 1

isA()方法会使用instanceof进行参数类型匹配,类似的方法还有anyInt(),anyObject(), 
isNull(),same(), startsWith()……

mock void方法
mock.updateUserById(“TestId”);    
EasyMock.expectLastCall().anytimes(); 
//EasyMock.expectLastCall().andThrow(new RuntimeException()).anytimes();
  • 1
  • 2
  • 3
多次调用返回不同值
EasyMock.expect(rs.next()).andReturn(true).times(2).andReturn(false).times(1);  
  • 1

PowerMock双剑合璧

  • Why:如果遇到了静态、final类型的类和方法,以及私有方法,EasyMock的动态代理局限性使得无法测试这些特性情况。
  • How:用了字节码操作技术直接对生成的字节码类文件进行修改,从而可以方便对静态,final类型的类和方法进行Mock,还可以对私有方法进行Mock,更可以对类进行部分Mock。
引入到工程
<properties>
    <powermock.version>1.6.6</powermock.version>
</properties>

<dependencies>
    <dependency>    
      <groupId>org.powermock</groupId>    
      <artifactId>powermock-api-easymock</artifactId>    
      <version>${powermock.version}</version>    
      <scope>test</scope>    
    </dependency>    
    <dependency>    
      <groupId>org.powermock</groupId>    
      <artifactId>powermock-module-junit4</artifactId>    
      <version>${powermock.version}</version>    
      <scope>test</scope>    
    </dependency>
</dependencies>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
基本用法

先“声明”,再“录制”,后使用 
- 声明powermock:当前测试类增加注解 @RunWith(PowerMockRunner.class) 
- 声明需要操作字节码的类 @PrepareForTest({clzz1.class, clzz2.class}) 
- 录制对象的行为(打桩) 
- 声明录制完成:PowerMock.replayAll

final类的静态方法
@RunWith(PowerMockRunner.class)
public class SystemPropertyMockDemoTest {         
    @Test        
    public void demoOfFinalSystemClassMocking() throws Exception {         
        PowerMock.mockStatic(System.class);         
        PowerMock.when(System.getProperty("property")).thenReturn("my property");         
        PowerMock.replayAll();
     //enjoy your mock
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

对于JDK的类如果要进行静态或final方法Mock时,不需要放在@PrepareForTest里面

@PrepareForTest({……}) 
注解既可以加在类层次上(对整个测试文件有效),也可以加在测试方法上(只对测试方法有效)。

Mock部分方法或私有方法Mock
@RunWith(PowerMockRunner.class)     
@PrepareForTest(DataService.class)    
public class DataServiceTest {    
    @Test    
    public void testReplaceData() throws Exception {    
        DataService tested = PowerMock.createPartialMock(DataService.class, "modifyData");//创建部分mock对象,只对modifyData方法Mock    
        PowerMock.expectPrivate(tested, "modifyData", "id", null).andReturn(true);//录制私有方法    
        PowerMock.replay(tested);    
        assertTrue(tested.deleteData(“id”));    
        PowerMock.verify(tested);    
    }    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
带构造函数的mock
File fileMock = PowerMock.createMockAndExpectNew(File.class, "directoryPath");
import com.wang.service.service.Service;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import static org.junit.Assert.assertNotNull;

/**
 * UserRegister Tester.
 *
 * @author <Authors name>
 * @version 1.0
 * @since <pre>六月 16, 2018</pre>
 */
public class UserRegisterTest {


    private HttpServletRequest request;
    private HttpServletResponse response;
    private HttpSession session;

    @Before
    public void before() throws Exception {
        // 创建request和response的Mock
        request = EasyMock.createMock(HttpServletRequest.class);
        response = EasyMock.createMock(HttpServletResponse.class);
        session = EasyMock.createMock(HttpSession.class);
    }

    @After
    public void after() throws Exception {
    }

    /**
     * Method: newService()
     */
    @Test
    public void testNewService() throws Exception {
//TODO: Test goes here... 
    }

    /**
     * Method: execute(HttpServletRequest req, HttpServletResponse resp)
     */
    @Test
    public void testExecute() throws Exception {
        Service service = UserRegister.newService();

        EasyMock.expect(request.getParameter("rUserName")).andReturn("UserRegisterTest").once();    //期望使用参数
        EasyMock.expect(request.getParameter("rUserPassword1")).andReturn("testtest").times(1);  //期望调用的次数

        EasyMock.replay(request);   //保存期望结果

        ServiceResult result = service.execute(request, response);

        assertNotNull(result.getPage());
        assertNotNull(result.getErrormsg());
    }

} 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值