PowerMockito的基本使用解析

网友投稿 616 2022-10-12


PowerMockito的基本使用解析

PowerMockito经常会结合Mockito使用,先说一下这2个的介绍:

1.Mockito和PowerMockito的简介

Mockito和PowerMockito是什么东西呢?他们有什么作用呢?

Mocktio和PowerMockito都是Mock的工具类,主要是java的类库,Mock就是伪装的意思。

他们适用于单元测试中,对于单元测试来说,我们不希望依赖于第三方的组件,比如数据库、Webservice等。在写单元测试的时候,我们如果遇到了这些需要依赖第三方的情况,我们可以使用Mock的技术,伪造出来我们自己想要的结果。

对于Java而言,mock的对象主要是Java 方法和 Java类。

下面我就介绍一下怎么使用Mockito和PowerMockito去进行Mock。

2.Mockito和PowerMockito的区别

在我看来,PowerMockito是Mockito的一种增强,他们的PowerMockito可以调用Mockito的方法,但是对于Mocktio不能Mock的对象或者方法,我们可以使用PowerMockito来实现。

比如Mockito不能用于static Method, final method, 枚举类, private method,这些我们都可以用PowerMockito来实现,当PowerMockito和mockito结合使用的时候,我们需要考虑兼容性的问题。

两者的版本需要兼容

Mockito

PowerMockito

2.8.9+

2.x

2.8.0-2.8.9

1.7.x

2.7.5

1.7.0RC4

2.4.0

1.7.0RC2

2.0.0-beta - 2.0.42-beta

1.6.5-1.7.0RC

1.10.8 - 1.10.x

1.6.2 - 2.0

1.9.5-rc1 - 1.9.5

1.5.0 - 1.5.6

1.9.0-rc1 & 1.9.0

1.4.10 - 1.4.12

1.8.5

1.3.9 - 1.4.9

1.8.4

1.3.7 & 1.3.8

1.8.3

1.3.6

1.8.1 & 1.8.2

1.3.5

1.8

1.3

1.7

1.2.5

Ref:https://github.com/powermock/powermock/wiki/Mockito

3.具体用法

本文实现实现需要构造的接口和需要返回值的接口

引入依赖

org.projectlombok

lombok

org.projectlombok

lombok

org.springframework

spring-context-support

org.springframework

spring-test

test

junit

junit

4.12

test

org.mockito

mockito-all

2.0.2-beta

test

org.powermock

powermock-module-junit4

1.7.4

test

org.powermock

powermock-api-mockito

1.7.4

test

需要Mock的类:

ProcessDB.java

package com.github.mock.simple.vo;

public class ProcessDB {

public ProcessDB(String ss){

System.out.println(ss + " Enter ProcessDB ...");

}

public ProcessDB(){

System.out.println("Enter ProcessDB ...");

}

public void getResultOfConnectDBNrwibOkZMDoReturn(String ss) {

System.out.println(ss + " Enter getResultOfConnectDBNoReturn ...");

}

public String getResultOfConnectDB() {

return "haha, Really went to the database";

}

}

需要测试的类:

IUserService.java

package com.github.mock.simple.user;

public interface IUserService {

public String testedMehtod();

}

UserServiceImpl.java

package com.github.mock.simple.user.impl;

import org.springframework.stereotype.Service;

import com.github.mock.simple.user.IUserService;

import com.github.mock.simple.vo.ProcessDB;

@Service

public class UserServiceImpl implements IUserService {

@Override

public String testedMehtod(){

System.out.println("Enter UserServiceImpl testedMehtod ...");

ProcessDB processDB = new ProcessDB("BB");

processDB.getResultOfConnectDBNoReturn("AA");

return processDB.getResultOfConnectDB();

}

}

BussinessService.java

package com.github.mock.simple.user.impl;

import com.github.mock.simple.vo.ProcessDB;

public class BussinessService {

public String testedMehtod() {

System.out.println("Enter BussinessService testedMehtod ...");

ProcessDB processDB = new ProcessDB("BB");

processDB.getResultOfConnectDBNoReturn("AA");

return processDB.getResultOfConnectDB();

}

}

测试类:

MockSpringSimpleTest.java

package com.github.mock.simple.test;

import java.text.MessageFormat;

import org.junit.Assert;

import org.junit.Before;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.mockito.InjectMocks;

import org.mockito.Mock;

import org.mockito.MockitoAnnotations;

import org.powermock.api.mockito.PowerMockito;

import org.powermock.core.classloader.annotations.PrepareForTest;

import org.powermock.modules.junit4.PowerMockRunner;

import org.powermock.modules.junit4.PowerMockRunnerDelegate;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.github.mock.simple.user.IUserService;

import com.github.mock.simple.user.impl.BussinessService;

import com.github.mock.simple.user.impl.UserServiceImpl;

import com.github.mock.simple.vo.ProcessDB;

@RunWith(PowerMockRunner.class)

@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)//Spring上下文

@PrepareForTest({BussinessService.class,UserServiceImpl.class})

@ContextConfiguration(locations = {"classpath:applicationContext-mock-inject.xml"})

public class MockSpringSimpleTest {

//使用Spring上下文

@Autowired

IUserService userService;

@Mock

ProcessDB processDB;

//不使用Spring上下文时,使用该注解

@InjectMocks

private BussinessService bussinessService;

@Before

public void initMocks() throws Exception {

MockitoAnnotations.initMocks(this);

//ReflectionTestUtils.setField(userService, "processDB", processDB);

PowerMockito.whenNew(ProcessDB.class).withArguments("BB").thenReturn(processDB);

// PowerMockito.whenNew(ProcessDB.class).withNoArguments().thenReturn(processDB);

}

@Test

public void mockConnectDB() {

String aa = "haha, everything is fake";

PowerMockito.when(processDB.getResultOfConnectDB()).thenReturn(aa);

PowerMockito.doNothing().when(processDB).getResultOfConnectDBNoReturn("AA");

System.out.println(bussinessService.testedMehtod());

Assert.assertEquals("haha, everything is fake", bussinessService.testedMehtod());

}

@Test

public void mockConnectDB2() {

try {

String aa = "haha, everything is fake";

PowerMockito.when(processDB.getResultOfConnectDB()).thenReturn(aa);

PowerMockito.doNothing().when(processDB).getResultOfConnectDBNoReturn("AA");

System.out.println(userService.testedMehtod());

Assert.assertEquals("haha, everything is fake", userService.testedMehtod());

} catch (Exception ex) {

System.out.println("--- getMessage ---");

System.out.println(ex.getMessage());

System.out.println();

System.out.println("--- toString ---");

System.out.println(ex.toString());

System.out.println();

// System.out.println("--- printStackTrace ---");

// StringWriter stringWriter = new StringWriter();

// PrintWriter printWriter = new PrintWriter(stringWriter);

// ex.printStackTrace(printWriter);

// System.out.println(stringWriter.toString());

// System.out.println();

System.out.println("--- printStackTrace DIY ---");

System.out.println(ex.getClass().getName() + ": " + ex.getMessage());

StringBuilder sbException = new StringBuilder();

for (StackTraceElement ele : ex.getStackTrace()) {

sbException.append(MessageFormat.format("\tat {0}.{1}({2}:{3})\n",

ele.getClassName(), ele.getMethodName(), ele.getFileName(), ele.getLineNumber()));;

}

System.out.println(sbException);

sbException = null;

// stringWriter = null;

// printWriter = null;

}

}

}

扫描注入xml

最后applicationContext-mock-inject.xml

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="

http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/context

http://springframework.org/schema/context/spring-context.xsd">

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="

http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/context

http://springframework.org/schema/context/spring-context.xsd">

对于没有实现类,但又被依赖的接口,在applicationContext-mock-inject.xml添加如下内容 (本文不需要):

同时在测试类里面添加下面的代码:

@Mock

iXxService iXxService;

在 @Before里面添加下面的代码

ReflectionTestUtils.setField(userService, "iXxService", iXxService);

测试结果

PowerMockito的使用技巧

当IT中有些依赖组件无法正常集成,需要mock支持测试,可以使用power mockito。

特别注意:

当对一个对象进行powermockito,应该在prepare方法,统一mock这个对象。然后在其他方法,分别进行调用when,否则,多个方法内进行mock,会出错。

比如有个 Service处于IT case的底层,普通的mock根本mock不进去,但我们又不能为了集成测试,为这个testcase单独开一个口子,注入mock对象。power mockito强大的mock能力在这里可以用上。

比如:

我的mock对象impalaService它在schmaMessagehandler类里new出来的,则需要加上注解。

首先在test 类的开头,加上注解头部,头部类是mock对象所在类。

@RunWith(PowerMockRunner.class)

@PrepareForTest({HttpClient.class,SchemaMessageHandler.class})

其次:

PooledImpalaService impalaService = PowerMockito.mock(PooledImpalaService.class);

PowerMockito.whenNew(PooledImpalaService.class).withArguments((ConfigurationanyObject()).thenReturn(impalaService);

doNothing().when(impalaService).createTable(anyString(),(Schema) anyObject());

使用powermockito,注意在用any()参数时候,比如

doNothing().when(impalaService).createTable(anyString(),(Schema) anyObject());

参数列表中,只要一个使用了any(),any****,则所有参数都要用any相关的参数,否则mock不成功。

总的来说,在it当中,只有你想mock一个对象,一定可以,比如你在A类中用到了B类,那么在prepareForTest中增加A类的注解。

如下:

@PrepareForTest({A.class})然后,在it中 声明一个B类,B b = PowerMockito.mock(B.class);这时候,就可以指定b的方法的返回值,或 PowerMockit.doNothing().when(b).方法名(),让该方法什么也不做。

最后,再讲A实例化。PowerMockit是讲究mock设置顺序的。一定要注意。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【计算机网络】理解网络传输基本流程 ( OSI七层模型 与 TCP/IP五/四层模型 ) 、网络分层中的封装和分用
下一篇:Linux内核中VLAN的实现过程(5)-设备初始化
相关文章

 发表评论

暂时没有评论,来抢沙发吧~