【个人笔记】寻找解决方法:测试类要new对象,但仅有的有参构造函数里存在无法执行的代码段

一.外部测试用例创建new对象时,构造函数里因执行super(context);会报错,寻找解决方法

// super调用到这里
public AbsAction(Context var1) {
        boolean var10000 = true;
        JniLib1606719255.cV(new Object[]{this, var1, 4});
    }

1.使用powermock.spy(new ActionExecuter(context));因还是会调用构造函数,Failed
2.不能使用打桩@Mock,因为需要测试该类中的其它方法(此为目的) Failed
3.反射:“获取类中的有残构造方法就可以通过反射执行这个有参构造方法就可以构建对象” ,Failed
4.不创建对象,直接调用方法,根本原理上就无法实现 Failed
5.PowerMockito.mockStatic(JniLib1606719255.class);也不行,会报错(安卓原生问题):Failed

java.lang.UnsatisfiedLinkError: android.util.Log.println_native(IILjava/lang/String;Ljava/lang/String;)I

	at android.util.Log.println_native(Native Method)
	at android.util.Log.e(Log.java:240)

6.外部新建类继承该源码类:因该类只有有参构造函数,继承出来的类中的构造函数还是要执行super才行,否则报错:There is no default constructor available in 'com.desaysv.adapter.sceneengine.ActionExecuter' Failed
7.在第6方法上,继承后,写一个有参构造函数,再写一个无参构造函数,也不行。和6同理 Failed
8.放弃,改源码,加个无参构造函数,也不行,和6、7同样情况 Failed
9.没法搞,该类暂无法单元测试,使用实机的灰盒继承测试

【2021-7-7更新】
10.可以使用 PowerMockito.suppress(MemberMatcher.constructor(xxx.class));来跳过xxx类的构造函数,包括类中new对象也可行!!

二、Powermockito.doNothing提示错误:

Cannot access org.mockito.stubbing.BaseStubber

1.添加mockito-all依赖,不行: testImplementation group: 'org.mockito', name: 'mockito-all', version: '1.10.19' Failed
2.Mockito-core 3.8+因将DoesNothing()改为了私有,无视即可,直接运行:

public static PowerMockitoStubber doNothing() {
        return POWERMOCKITO_CORE.doAnswer(new DoesNothing());
    }
``

```cpp
//.Mockito-core 3.8
   private DoesNothing() {}

三、mock对象空指针问题,(记录)

//测试代码
repositoryProxy = PowerMockito.mock(RepositoryProxy.class);
repositoryProxy.bind(Mockito.any(),Mockito.any(),Mockito.any());

会报错:

java.lang.NullPointerException
	at com.desaysv.adapter.sceneengine.manager.MediaManagerTest.init(MediaManagerTest.java:57)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:316)
	at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
	at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:300)

四、Mockito.verify()参数报错问题

//源码
Mockito.verify(repositoryProxy).bind(context,Target.RADIO,Mockito.any());
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
3 matchers expected, 1 recorded:
-> at com.desaysv.adapter.sceneengine.manager.MediaManagerTest.init(MediaManagerTest.java:59)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

方法:按照要求修改参数,如Matchers.eq(Target.RADIO),改为:

Mockito.verify(repositoryProxy).bind(Matchers.eq(context),Matchers.eq(Target.RADIO),Mockito.any());

此来源:https://stackoverflow.com/questions/14845690/mockito-invaliduseofmatchersexception
五、MeadiPlayer等安卓原生类无法被mock

六、今天ROBO配置与测试卡在如下报错:2021-04-01

WARNING: No manifest file found at .\AndroidManifest.xml.
No such manifest file: .\AndroidManifest.xml
Falling back to the Android OS resources only.
To remove this warning, annotate your test class with @Config(manifest=Config.NONE).
[Robolectric] com.desaysv.adapter.sceneengine.manager.RoboTest.myTest: sdk=27; resources=legacy
[Robolectric] NOTICE: legacy resources mode is deprecated; see http://robolectric.org/migrating/#migrating-to-40

问题点可能出现在@config()中无法配置如下内容导致,仍待研究。。。

constants = BuildConfig.class

七、模拟测试回调函数时,用powermock或者Mockito.doAnswer()都可以,因此可以运用在安卓实机测试上,如:

//onPreparedListener = (MediaPlayer.OnPreparedListener)ol;获取到要测试的回调函数
doAnswer(new Answer<Object>() {
            public Object answer(InvocationOnMock invocation) throws IOException {
                Object[] args = invocation.getArguments();
                Object ol = args[0];
                if(ol instanceof MediaPlayer.OnPreparedListener){
                    onPreparedListener = (MediaPlayer.OnPreparedListener)ol;
                }
                return null;
            }
        }).when(mediaPlayer).setOnPreparedListener(Mockito.any(MediaPlayer.OnPreparedListener.class));

来源模仿:http://www.voidcn.com/article/p-kpzdmtlj-bsv.html
八、安卓实机测试注意 场景/response/空指针 判断

【8-24】更新

九、安卓单元测试中,枚举类emun不能放在prepareForTest中,也不能用mockstatic,否则当遇到switch时会报错。直接用 枚举类.成员 就行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值