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());
}
}