使用 mockito 模拟 AccountManager

编程入门 行业动态 更新时间:2024-10-27 04:29:49
本文介绍了使用 mockito 模拟 AccountManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我在活动测试中使用 mockito 来模拟 AccountManager.

I'm using mockito to mock AccountManager inside an Activity test.

所以,我的测试代码如下:

So, my test code is as follows:

public class PressuresListActivityUnitTest extends ActivityUnitTestCase<PressuresListActivity> { // Test data. private static final String ACCOUNT_TYPE = "com.example.android"; private static final Account ACCOUNT_1 = new Account("account1@gmail", ACCOUNT_TYPE); private static final Account ACCOUNT_2 = new Account("account2@gmail", ACCOUNT_TYPE); private static final Account[] TWO_ACCOUNTS = { ACCOUNT_1, ACCOUNT_2 }; @Mock private AccountManager mMockAccountManager; public PressuresListActivityUnitTest() { super(PressuresListActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); setupDexmaker(); // Initialize mockito. MockitoAnnotations.initMocks(this); } public void testAccountNotFound() { Mockito.when(mMockAccountManager.getAccounts()) .thenReturn(TWO_ACCOUNTS); Intent intent = new Intent(Intent.ACTION_MAIN); startActivity(intent, null, null); } /** * Workaround for Mockito and JB-MR2 incompatibility to avoid * java.lang.IllegalArgumentException: dexcache == null * * @see <a href="code.google/p/dexmaker/issues/detail?id=2"> * code.google/p/dexmaker/issues/detail?id=2</a> */ private void setupDexmaker() { // Explicitly set the Dexmaker cache, so tests that use mockito work final String dexCache = getInstrumentation().getTargetContext().getCacheDir().getPath(); System.setProperty("dexmaker.dexcache", dexCache); }

以及将要测试的活动的 onCreate 方法:

And the onCreate mthod of activity that will be tested:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pressures_list); AccountManager am = AccountManager.get(this); Account[] accounts = am.getAccounts(); if (accounts.length > 0) { Log.i("TAG", "it works!"); } }

但是当我运行测试时,AccountManager.getAccounts 不会返回测试中指定的帐户.

But when I run the test, AccountManager.getAccounts does NOT return the accounts specified in the test.

有什么想法吗?

推荐答案

经过一番研究,终于解决了这个问题.

After some research, I finally solved the problem.

Android 提供了一些在测试中使用的类,例如 MockContext、IsolatedContext.

Android provides some classes to be used inside the tests, like MockContext, IsolatedContext.

developer.android/reference/android/测试/模拟/MockContext.html

developer.android/reference/android/test/隔离上下文.html

为了完成这项工作,我创建了 ContextWrapper 的子类并覆盖了(??) getSystemService 方法.

To get this done, I created a subclass of ContextWrapper and overrode(??) getSystemService method.

根据文档:

Context 的代理实现,只是将其所有调用委托给另一个 Context.可以子类化以修改行为,而无需更改原始 Context."

"Proxying implementation of Context that simply delegates all of its calls to another Context. Can be subclassed to modify behavior without changing the original Context."

developer.android/reference/android/content/ContextWrapper.html

通过这种方式,我使用常规 AndroidActivityUnitTestCase 在 Activity 中注入了原始上下文,但根据我的需要进行了修改.

This way, I injected the original context, but modified to fit my needs, inside the Activity using a regular AndroidActivityUnitTestCase.

看看这个:

public class FakeContextWrapper extends ContextWrapper { private static final String ACCOUNT_TYPE = "com.example.android"; private static final Account ACCOUNT_1 = new Account("account1@gmail", ACCOUNT_TYPE); private static final Account ACCOUNT_2 = new Account("account2@gmail", ACCOUNT_TYPE); private static final Account[] TWO_ACCOUNTS = { ACCOUNT_1, ACCOUNT_2 }; @Mock private AccountManager mMockAccountManager; public FakeContextWrapper(Context base) { super(base); MockitoAnnotations.initMocks(this); Mockito.when(mMockAccountManager.getAccounts()).thenReturn(TWO_ACCOUNTS); } @Override public Object getSystemService(String name) { if (Context.ACCOUNT_SERVICE.equals(name)) { return mMockAccountManager; } else { return super.getSystemService(name); } } }

内部测试:

public void testAccountNotFound() { Context context = new FakeContextWrapper(getInstrumentation().getTargetContext()); setActivityContext(context); Intent intent = new Intent(Intent.ACTION_MAIN); startActivity(intent, null, null); // TODO assertions. }

最后是被测Activity:

Finally, the Activity under test:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pressures_list); AccountManager am = AccountManager.get(this); Account[] accounts = am.getAccounts(); if (accounts.length == 0) { // TODO call login. } else { Log.i("TAG", "it works!"); } }

更多推荐

使用 mockito 模拟 AccountManager

本文发布于:2023-10-31 07:09:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1545388.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:mockito   AccountManager

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!