我有一个像这样的简单的android类常量:
public class Consts extends BaseConstants { public static final String SCHEME = "http"; // Tag used to cancel the request public static final String TAG_JsON = "Json_obj_req";}
其中没有其他内容,因此应易于模拟.我在测试用例中称其为:
Mockito.spy(Consts.class); …这是失败的.下面是测试用例文件:
public class ApplicationTest extends ActivityInstrumentationTestCase2<MainActivity> { MainActivity mActivity; public Applicationtest() { super(MainActivity.class); } @OverrIDe protected voID setUp() throws Exception { super.setUp(); setActivityInitialtouchMode(false); mActivity = getActivity(); } public voID testUrlValID() { Mockito.spy(Consts.class); }}
这是测试用例的logcat输出:
Running testsTest running startedorg.mockito.exceptions.base.MockitoException:Cannot mock/spy class java.lang.classMockito cannot mock/spy following:- final classes- anonymous classes- primitive types
——-更新:
我想监视我的mainActivity类,但得到了同样的Mockito异常:这是我正在测试的类:
import androID.os.Bundle;import androID.vIEw.Menu;import androID.vIEw.MenuItem;public class MainActivity extends ListPageActivity { @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); if (savedInstanceState == null) { getFragmentManager().beginTransaction() .add(R.ID.container, new SummaryFragment(),"SummaryFragment") .commit(); } loadBrandSound(); if (!isNetworkAvailable()) showToast(getString(R.string.no_network)); } @OverrIDe public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @OverrIDe public boolean onoptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroIDManifest.xml. int ID = item.getItemID(); //noinspection SimplifiableIfStatement if (ID == R.ID.action_settings) { return true; } return super.onoptionsItemSelected(item); }}
这是我的简单测试用例:
import androID.test.ActivityInstrumentationTestCase2;import androID.Widget.button;import androID.Widget.EditText;import org.mockito.Mockito;public class ApplicationTest extends ActivityInstrumentationTestCase2<MainActivity> { MainActivity mActivity; private button goBtn; private EditText et_query; private Recyclerlistadapter mAdapter; public Applicationtest() { super(MainActivity.class); } @OverrIDe protected voID setUp() throws Exception { super.setUp(); setActivityInitialtouchMode(false); mActivity = getActivity(); goBtn=(button)mActivity.findVIEwByID( R.ID.btn_go); et_query = (EditText)mActivity.findVIEwByID(R.ID.et_query); } @OverrIDe protected voID tearDown() throws Exception { super.tearDown(); } public voID testPreconditions() { assertTrue(mActivity.isNetworkAvailable()); isLayoutValID(); } public voID isLayoutValID(){ assertNotNull(goBtn); } public voID testSomething(){ Mockito.spy(MainActivity.class); }}
为什么它在间谍线上失败了?这是日志:
Running testsTest running startedorg.mockito.exceptions.base.MockitoException:Cannot mock/spy class java.lang.classMockito cannot mock/spy following:- final classes- anonymous classes- primitive typesat mypackage.ApplicationTest.testSomething(ApplicationTest.java:65)at java.lang.reflect.Method.invokeNative(Native Method)at androID.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)at androID.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)at androID.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)at androID.test.AndroIDTestRunner.runTest(AndroIDTestRunner.java:191)at androID.test.AndroIDTestRunner.runTest(AndroIDTestRunner.java:176)at androID.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)at androID.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1729)Finish
解决方法:
与Mockito.mock(Class T clazz)不同,Mockito.spy(T instance)采用一个实例.但是,两者都返回一个实例.您正在寻找替换静态字段,而不是实例方法.
Mockito无法模拟静态成员或最终类,因为它主要通过创建匿名代理实现或子类来工作.子类不能覆盖静态方法或扩展最终类,因此Java编译器采用了跳过Mockito提供的任何实现的快捷方式. (对于静态最终常数inlined at compile time尤其如此.)
尽管PowerMockito可以重写被测系统代码以模拟最终和静态方法调用,但是它对字段没有帮助.附加级别的间接访问可能是更好的解决方案.
public class MyApplication extends Application { public boolean isUrlValID(String url) { return isUrlValID(url, Consts.SCHEME, Consts.TAG_JsON); } static boolean isUrlValID(String url, String scheme, String JsonTag) { // ... }}public class MyApplicationTest { @Test public voID urlValIDShoulDWork() { assertTrue(MyApplication.isUrlValID(VALID_URL, "fakescheme", "faketag"); }}
或者,使Consts根据访问器方法(getScheme)而不是字段(scheme)进行 *** 作.诸如ProGuard之类的工具通常可以内联简单的方法调用,因此在生产中不应太慢或冗长,并且您将有更多的机会替代测试中的实现.有关在测试中插入/注入模拟实现的更多技术,请参见see this SO question.
总结以上是内存溢出为你收集整理的无法监视Android类全部内容,希望文章能够帮你解决无法监视Android类所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)