junit中比较常用的三种情形:
1.mock log4j,对log进行测试
2.mock DAO,使得测试脱离真实的DB环境,不需要连数据库
3.mock Http,使得测试脱离外部环境,不需要真的去进行Http请求
package com.project.service;
import com.project.bean.User;
import com.project.dao.UserDAO;
import com.project.mock.MockLog;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({TargetService.class, LogFactory.class, DefaultHttpClient.class}) // 告诉PowerMock哪些类需要被mock
public class TargetServiceTest {
private MockLog mLog;
@Before
public void setUp() {
// 实例化自己的mock log对象
mLog = new MockLog();
// 通过反射对TargetService中的变量log进行mock
Whitebox.setInternalState(TargetService.class, "log", mLog);
}
/**
* mock log4j示例
* @throws Exception
*/
@Test
public void testLog4j() throws Exception {
// mock
TargetService target = PowerMock.createPartialMock(TargetService.class, "method1");
PowerMock.expectPrivate(target, "method1").andThrow(new IOException());
PowerMock.replay(target);
// 验证是否抛出IOException
Assert.assertEquals(IOException.class , mLog.getExceptionList().get(0).getClass());
// 验证log的条数是否正确
Assert.assertEquals(1, mLog.getLogList().size());
// 验证log输出的错误信息是否正确
Assert.assertEquals("system error" , mLog.getLogList().get(0));
PowerMock.verify(target);
}
/**
* mock DAO,使得测试脱离真实的DB环境,不需要连数据库
* @throws Exception
*/
@Test
public void testMockDAO() throws Exception {
// mock
TargetService target = PowerMock.createPartialMock(TargetService.class, "method1", "method2");
// mock userDAO
UserDAO userDAO = PowerMock.createMock( UserDAO.class );
// 返回数据的准备
User user = new User();
int userId = 28;
user.setNickname( "ニックネーム" );
user.setUserid( userId );
// 既然是mock的dao,那么想得到什么都由自己定,脱离了真实的DB环境
EasyMock.expect( userDAO.getUser( EasyMock.anyInt() ) ).andReturn( user );
PowerMock.replay(userDAO);
// 将mock userDao注入到目标类中
target.setUserDAO( userDAO );
PowerMock.replay(target);
// Dao已经被mock了,接下来根据自己的需求做一些事情
...
// 验证正确性
Assert.assertEquals(expected, actual);
PowerMock.verify(userDAO);
PowerMock.verify(target);
}
/**
* mock Http,使得测试脱离外部环境,不需要真的去进行Http请求
* @throws Exception
*/
@Test
public void testMockHttp() throws Exception {
// mock HttpClient
DefaultHttpClient httpClient = PowerMock.createMock(DefaultHttpClient.class);
PowerMock.expectNew(DefaultHttpClient.class).andStubReturn(httpClient);
// mock HttpResponse
HttpResponse response = PowerMock.createMock(HttpResponse.class);
EasyMock.expect(httpClient.execute(EasyMock.anyObject(HttpUriRequest.class))).andStubReturn(response);
StatusLine statusLine = PowerMock.createMock(StatusLine.class);
EasyMock.expect(response.getStatusLine()).andStubReturn(statusLine);
// 设定期望的http status code,也可以是404,500等
EasyMock.expect(statusLine.getStatusCode()).andStubReturn(200);
HttpEntity entity = PowerMock.createMock(HttpEntity.class);
EasyMock.expect(response.getEntity()).andStubReturn(entity);
// 设定期望的http响应结果,这里用一个字符串来作为返回值
InputStream inputStream = new ByteArrayInputStream("code:E01".getBytes());
EasyMock.expect(entity.getContent()).andReturn(inputStream);
// 已经得到了期望的Http请求结果,接下来根据自己的需求做一些事情
...
PowerMock.replayAll();
// 验证正确性
Assert.assertEquals(expected, actual);
PowerMock.verifyAll();
}
}
测试log4j需要的自定义的mock log类:
package com.project.mock;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
/**
* 这是一个自定义的log类,用于mock真实的log4j对象,它可以模拟log4j的各种动作,并且可以订制各种我们希望的动作
* 这里只模仿两个动作,一个是单纯的接收一条message,一个是接收message同时接收一个exception
* 这样一来,真实代码中要用到log4j对象记录log的地方,都被这个mock log给替换了,并且所有记录的信息都被记录到这个对象中,供测试用
* @throws Exception
*/
public class MockLog implements Log {
private List<Object> logList = new ArrayList<Object>();
private List<Throwable> exceptionList = new ArrayList<Throwable>();
@Override
public void debug(Object arg0) {
logList.add(arg0);
}
@Override
public void debug(Object arg0, Throwable arg1) {
logList.add(arg0);
exceptionList.add( arg1 );
}
@Override
public void error(Object arg0) {
logList.add(arg0);
}
@Override
public void error(Object arg0, Throwable arg1) {
logList.add(arg0);
exceptionList.add( arg1 );
}
@Override
public void fatal(Object arg0) {
}
@Override
public void fatal(Object arg0, Throwable arg1) {
logList.add(arg0);
exceptionList.add( arg1 );
}
@Override
public void info(Object arg0) {
logList.add(arg0);
}
@Override
public void info(Object arg0, Throwable arg1) {
logList.add(arg0);
exceptionList.add( arg1 );
}
@Override
public boolean isDebugEnabled() {
return false;
}
@Override
public boolean isErrorEnabled() {
return false;
}
@Override
public boolean isFatalEnabled() {
return false;
}
@Override
public boolean isInfoEnabled() {
return false;
}
@Override
public boolean isTraceEnabled() {
return false;
}
@Override
public boolean isWarnEnabled() {
return false;
}
@Override
public void trace(Object arg0) {
logList.add(arg0);
}
@Override
public void trace(Object arg0, Throwable arg1) {
logList.add(arg0);
exceptionList.add( arg1 );
}
@Override
public void warn(Object arg0) {
logList.add(arg0);
}
@Override
public void warn(Object arg0, Throwable arg1) {
logList.add(arg0);
exceptionList.add( arg1 );
}
public List<Object> getLogList() {
return logList;
}
public void setLogList(List<Object> logList) {
this.logList = logList;
}
public void setExceptionList( List<Throwable> exceptionList ) {
this.exceptionList = exceptionList;
}
public List<Throwable> getExceptionList() {
return exceptionList;
}
}
分享到:
相关推荐
标题“使用PowerMock来Mock静态函数”指的是如何利用PowerMock库来对Java中的静态方法进行模拟测试。静态方法由于其非实例化特性,通常难以通过常规的单元测试方式进行隔离和测试,因为它们不依赖于对象的状态。...
PowerMock允许我们使用`@PrepareForTest`注解指定需要模拟的类,并通过`PowerMockito.mockStatic`或`Mockito.when`来模拟私有方法。 下面是一段使用PowerMock模拟静态方法和私有方法的示例代码: ```java import ...
Instant Mock Testing with PowerMock 7 Saying Hello World! (Simple) 8 Getting and installing PowerMock (Simple) 14 Mocking static methods (Simple) 22 Verifying method invocation (Simple) 28 Mocking ...
3. **模拟静态方法**:使用`PowerMockito.mockStatic(Class<?> clazz)`来模拟静态方法。然后通过`when`和`thenReturn`(或其他方法)来定义静态方法的行为。 4. **模拟私有方法**:首先,需要使用`PowerMockito.spy...
赠送jar包:powermock-module-junit4-2.0.9.jar; 赠送原API文档:powermock-module-junit4-2.0.9-javadoc.jar; 赠送源代码:powermock-module-junit4-2.0.9-sources.jar; 赠送Maven依赖信息文件:powermock-...
在Java开发中,有时我们需要对不可Mock的对象进行单元测试,PowerMock提供了解决这类问题的能力。 标题中的"powermock依赖jar文件.rar"指的是包含PowerMock运行所需的JAR库文件的压缩包。这个压缩包可能是用户在...
PowerMock 提供了 `PowerMockito.mockStatic` 方法,允许我们指定静态方法的行为,从而在测试中隔离静态方法的依赖。 3. **构造函数模拟**: 有些情况下,被测试类可能依赖于私有构造函数或不可实例化的类。...
4. **模拟构造函数**:对于不允许mock的构造函数,PowerMock可以帮助我们在测试中创建特定的实例。 5. **控制静态初始化器**:静态初始化器可能在不期望的时候被执行,PowerMock可以禁用它们,避免干扰测试。 通过...
【PowerMock实战教学】是由汪文君主讲的一系列教程,专注于讲解如何使用PowerMock这一强大的Java单元测试框架。PowerMock是在easymock和mockito的基础上构建的,旨在提供更多的功能,解决传统mock框架无法处理的一些...
赠送jar包:powermock-module-junit4-common-2.0.9.jar; 赠送原API文档:powermock-module-junit4-common-2.0.9-javadoc.jar; 赠送源代码:powermock-module-junit4-common-2.0.9-sources.jar; 赠送Maven依赖信息...
在后续章节中,将会进一步深入讲解PowerMock的高级特性,比如如何模拟局部变量(MockLocalVariable),如何模拟静态方法(MockStatic)以及如何使用验证(Verifying)。此外,本书还介绍了如何模拟私有方法、构造...
4. 在测试方法中使用Mock对象。 5. 使用`verify()`确保所有录制的方法都被调用。 **其他用法** - 指定期望的调用次数。 - 指定返回值。 - 处理异常。 - 创建自定义的返回值和异常。 **PowerMock的引入** ...
4. 使用Mockito的API创建mock对象并设置期望行为。 5. 使用PowerMock的API模拟静态方法、final类或方法等。 6. 编写测试方法,调用要测试的代码,并使用Mockito验证方法调用是否符合预期。 通过以上步骤,开发者...
在后端开发中,Mock 可以使用框架如 Mockito、PowerMock、Mockserver、Moco 等,对服务的请求和响应进行模拟。 Mock 的好处包括: * 可以并行工作,不需要等待依赖方的开发完成 * 可以方便构造出各种异常的场景,...
4. **Answer Interface**: PowerMock的`Answer`接口用于自定义模拟方法的响应。当你需要根据调用参数动态返回结果时,可以实现`Answer`接口,并在`answer`方法中编写业务逻辑。 5. **Argument Matcher**: `...
例如,使用PowerMock模拟难以测试的部分,用Mockito定义mock对象的行为,最后由JUnit执行并报告测试结果。通过这种方式,开发者可以确保代码的质量和可靠性,提高软件的稳定性。同时,这个版本的测试套件也意味着它...
这个压缩包“PowerMock.zip”可能包含PowerMock库的jar文件和其他相关资源,帮助开发者在他们的项目中集成和使用PowerMock。 PowerMock 的核心功能在于它的模拟能力。在单元测试中,我们通常希望隔离被测试代码,只...