android powermock,Android 单元测试 PowerMock框架的使用总结

在安卓中我们常用Junit + Mockito + PowerMock 组合进行测试。PowerMock是拓展Mockito,主要是为了解决Mockito 框架不支持mock匿名类、final类、static方法、private方法的问题,PowerMock内部调用了Mockito的方法(如:PowerMockito.when()内部调用的是Mockito.when())。

PowerMock的导入

testImplementation "org.powermock:powermock-module-junit4:1.7.3"

testImplementation "org.powermock:powermock-module-junit4-rule:1.7.3"

testImplementation "org.powermock:powermock-api-mockito2:1.7.3" //注意这里是mockito2

testImplementation "org.powermock:powermock-classloading-xstream:1.7.3"

PowerMock使用

首先我们定义一个Fruit类,Banana继承于它。其中有我们后面需要mock的static、private等方法。

abstract class Fruit {

private String fruit = "水果";

public String getFruit() {

return fruit;

}

}

public class Banana extends Fruit {

private static String COLOR = "黄色的";

private static String SIZE = "BIG";

private String place = "here";

public Banana() {}

public String getPlace() {

return place;

}

public static final String getColor() {

return COLOR;

}

private static String getSize() {

return SIZE;

}

public String getBananaInfo() {

return flavor() + getColor();

}

private String flavor() {

return "甜甜的";

}

public final boolean isLike() {

return true;

}

private final String getPrice() {

return "10";

}

public String privateFinal() {

return getPrice();

}

}

定义Mock类,:

方法一:

@RunWith(PowerMockRunner.class)

@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })

public class PowerMockito {

@Test

@PrepareForTest({Banana.class})

public void testMethod() throws Exception {

}

}

首先使用PowerMock必须在类名上加注@RunWith(PowerMockRunner.class),在方法上添加注解@PrepareForTest,注解@PrepareForTest里写的是要mock的方法所在的类。@PowerMockIgnore用于忽略mock的类,"android.*" 忽略android的相关类,因为我们使用Robolectric处理了;"org.mockito.*","org.robolectric.*" 忽略Mockito和Robolectric的相关类,因为我们不应该mock它们自己。

方法二:

有时我们会使用多个测试框架,可能@RunWith会占用,这时我们可以使用@Rule

@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })

public class PowerMockito {

@Rule

public PowerMockRule rule = new PowerMockRule();

@Test

@PrepareForTest({Banana.class})

public void testMethod() throws Exception {

}

}

使用方法总结,(final)表示final可有可无:

1、Mock public (final):

@Test

@PrepareForTest({Banana.class})

public void testMethod() throws Exception {

Banana mBanana = PowerMockito.mock(Banana.class);

PowerMockito.when(mBanana.isLike()).thenReturn(false);

Assert.assertFalse(mBanana.isLike());

}

2、Mock public static (final):

@Test

@PrepareForTest({Banana.class})

public void testMethod() throws Exception {

PowerMockito.mockStatic(Banana.class);

PowerMockito.when(Banana.getColor()).thenReturn("green");

Assert.assertEquals("green", Banana.getColor());

}

3、Mock private (final):

@Test

@PrepareForTest({Banana.class})

public void testMethod() throws Exception {

Banana banana = PowerMockito.mock(Banana.class);

PowerMockito.when(banana.getBananaInfo()).thenCallRealMethod();

PowerMockito.when(banana, "flavor").thenReturn("苦苦的");

Assert.assertEquals("苦苦的黄色的", banana.getBananaInfo());

}

4、Mock private static (final): 无法模拟

5、更改类的私有static常量,不能是final:

@Test

@PrepareForTest({Banana.class})

public void testMethod() throws Exception {

Whitebox.setInternalState(Banana.class, "COLOR", "red");

Assert.assertEquals("red", Banana.getColor());

}

6、跳过私有方法:

@Test

@PrepareForTest({Banana.class})

public void testMethod() throws Exception {

PowerMockito.suppress(PowerMockito.method(Banana.class, "flavor"));

Assert.assertEquals("null黄色的", mBanana.getBananaInfo());

}

7、更改父类私有变量,不能是final:

@Test

@PrepareForTest({Banana.class})

public void testMethod() throws Exception {

Banana mBanana = new Banana();

MemberModifier.field(Banana.class, "fruit").set(mBanana, "蔬菜");

Assert.assertEquals("蔬菜", mBanana.getFruit());

}

8、Mock 构造方法:

@Test

@PrepareForTest({Banana.class})

public void testMethod() throws Exception {

Banana mBanana = PowerMockito.mock(Banana.class);

PowerMockito.when(mBanana.getBananaInfo()).thenReturn("大香蕉");

//如果new新对象,则返回这个上面设置的这个对象

PowerMockito.whenNew(Banana.class).withNoArguments().thenReturn(mBanana);

//new新的对象

Banana newBanana = new Banana();

Assert.assertEquals("大香蕉", newBanana.getBananaInfo());

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值