我使用mockito来模拟活动测试中的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);
}以及将要测试的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不会返回测试中指定的帐户。
有什么想法吗?
发布于 2014-11-18 12:24:20
经过一番研究,我终于解决了这个问题。
Android提供了一些在测试中使用的类,如MockContext、IsolatedContext。
http://developer.android.com/reference/android/test/mock/MockContext.html
http://developer.android.com/reference/android/test/IsolatedContext.html
为了完成这个任务,我创建了一个ContextWrapper子类并重写了(?)getSystemService法
根据文件:
“代理上下文的实现,该实现仅将其所有调用委托给另一个上下文。可以子类化以修改行为而不更改原始上下文。”
http://developer.android.com/reference/android/content/ContextWrapper.html
通过这种方式,我使用一个常规的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.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.
}最后,所测试的活动:
@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!");
}
}发布于 2014-11-14 20:15:17
莫奇托不是这样工作的。
import static org.mockito.Mockito.*;
...
public void testAccountNotFound() {
AccountManager am = mock(AccountManager.class);
when(am.getAccounts()).thenReturn(TWO_ACCOUNTS);
// this is how you unit test something
assertTrue(am.getAccounts().size == 2);
}
public void testMoreRealWorldExample() {
AccountManager am = mock(AccountManager.class);
when(am.getAccounts()).thenReturn(TWO_ACCOUNTS);
/* try and create an account; createNewAccount() will call
getAccounts() to find out how many accounts there already
are in the system, and due to the above injection, it would
think there are already two. Thus we can test to make sure
users cannot create three or more accounts.
*/
boolean accountCreated = am.createNewAccount();
// maximum two accounts are allowed, so this should return false.
assertFalse(accountCreated);
}不能直接使用mockito在对象中任意注入值,然后运行Activity。Mockito用于单元测试您的对象,理想的情况下是对Android特定对象的最小引用,尽管某些引用是不可避免的。
请阅读食谱更接近了,因为它非常彻底。
如果你想模仿整个Activity,你需要看上去像在罗波利克
https://stackoverflow.com/questions/26937001
复制相似问题