PowerMock处理特殊的单元测试

背景

代码设计并不总是尽善尽美,有些单元测试是Mockito力不从心的。
这时候就需要PowerMock ,这个框架是对Mockito增强。
下面展示几个常用场景
- mock静态方法
- 跳过私有方法
- 更改子类无法访问的父类私有field
- 更改类的私有static常量
- 模拟New构造函数

示例

首先引入Maven依赖

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>1.7.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>1.7.0</version>
            <scope>test</scope>
        </dependency>

要测试的业务类包含了几个特殊用例


abstract class MyParent {

    private String parentValue = "parent";

    private String getMessageContent() {
        return parentValue;
    }

    protected String getParentMessage() {
        return getMessageContent();
    }

}

public class Mytest extends MyParent {

    private static String BID = "999";

    public Mytest() {

    }

    public static String getBid() {
        return BID;
    }

    public static String getMessage() {
        return "hello";
    }

    public String sendEmail() {
        String response = "send email";
        System.out.println(response);
        response = sendMessage("success");
        return response;
    }

    private String sendMessage(String status) {
        System.out.println("send message " + status);
        return "send message " + status;
    }
}

编写单元测试


import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.api.support.membermodification.MemberModifier;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;


@RunWith(PowerMockRunner.class) //以PowerMock启动Junit test
@PrepareForTest({Mytest.class}) //预处理要mock的类,在字节码的级别更改类的行为
public class Testmethod {
    @Test
    public void testStaticMethod() {//mock静态方法
        PowerMockito.mockStatic(Mytest.class);
        Mockito.when(Mytest.getMessage()).thenReturn("world");
        Assert.assertEquals("world", Mytest.getMessage());
    }

    @Test
    public void skipPrivateMethod() {//跳过私有方法
        Mytest t = new Mytest();
        PowerMockito.suppress(PowerMockito.method(Mytest.class, "sendMessage", String.class));  //类,方法名,参数类
        String response = t.sendEmail();
        Assert.assertTrue(response == null);//跳过了sendMessage方法,返回为null
    }

    @Test
    public void changeParentPrivate() {//更改子类无法访问的父类私有field
        Mytest t = new Mytest();
        try {
            MemberModifier.field(Mytest.class, "parentValue").set(
                    t, "tomcat");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        Assert.assertEquals("tomcat", t.getParentMessage());//父类私有field已经被更改
    }

    @Test
    public void changeBid() {//更改类的私有static常量
        Whitebox.setInternalState(Mytest.class, "BID", "888");
        Assert.assertEquals("888", Mytest.getBid());
    }

    @Test
    public void mockNew() throws Exception {//模拟New构造方法
        Mytest test = Mockito.mock(Mytest.class);
        Mockito.when(test.getParentMessage()).thenReturn("hello");

        PowerMockito.whenNew(Mytest.class).withNoArguments().thenReturn(test);

        Mytest testNew = new Mytest();

        Assert.assertEquals("hello", testNew.getParentMessage());
    }
}

已知问题

PowerMock实现了自己的类加载器,占用内存大,容易造成内存不足:OutOfMemoryError

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值