gpt4 book ai didi

android - 使用 mockito 模拟 AccountManager

转载 作者:太空狗 更新时间:2023-10-29 16:16:09 25 4
gpt4 key购买 nike

我正在使用 mockito 在 Activity 测试中模拟 AccountManager。

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

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.com", ACCOUNT_TYPE);
private static final Account ACCOUNT_2 = new Account("account2@gmail.com", 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="https://code.google.com/p/dexmaker/issues/detail?id=2">
* https://code.google.com/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);
}

以及将要测试的 Activity 的 onCreate 方法:

@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 不会返回测试中指定的帐户。

有什么想法吗?

最佳答案

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

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

http://developer.android.com/reference/android/test/mock/MockContext.html

http://developer.android.com/reference/android/test/IsolatedContext.html

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

根据文档:

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

http://developer.android.com/reference/android/content/ContextWrapper.html

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

检查一下:

public class FakeContextWrapper extends ContextWrapper {

private static final String ACCOUNT_TYPE = "com.example.android";

private static final Account ACCOUNT_1 = new Account("account1@gmail.com", ACCOUNT_TYPE);
private static final Account ACCOUNT_2 = new Account("account2@gmail.com", 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:

@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!");
}
}

关于android - 使用 mockito 模拟 AccountManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26937001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com