Make ImapStore tests use mocks where possible

Change-Id: I2a1d5e7d3cc3b105a24a5fc29772bcd4a0308ad3
This commit is contained in:
Ben Komalo 2011-04-25 15:46:50 -04:00
parent 8dc402b28a
commit 1611d0baed
4 changed files with 199 additions and 10 deletions

View File

@ -26,8 +26,6 @@ import android.os.Bundle;
import android.util.Log;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
/**
* A bridge class to the email vendor policy apk.

View File

@ -42,6 +42,7 @@ import com.android.emailcommon.provider.EmailContent.HostAuth;
import com.android.emailcommon.service.EmailServiceProxy;
import com.android.emailcommon.utility.Utility;
import com.beetstra.jutf7.CharsetProvider;
import com.google.common.annotations.VisibleForTesting;
import android.content.Context;
import android.os.Build;
@ -99,7 +100,7 @@ public class ImapStore extends Store {
private String mPassword;
private String mLoginPhrase;
private String mIdPhrase = null;
private static String sImapId = null;
@VisibleForTesting static String sImapId = null;
/*package*/ String mPathPrefix;
/*package*/ String mPathSeparator;
@ -118,7 +119,7 @@ public class ImapStore extends Store {
* requests. This cache lets us make sure we always reuse, if possible, for a given
* folder name.
*/
private HashMap<String, ImapFolder> mFolderCache = new HashMap<String, ImapFolder>();
private final HashMap<String, ImapFolder> mFolderCache = new HashMap<String, ImapFolder>();
/**
* Next tag to use. All connections associated to the same ImapStore instance share the same
@ -219,7 +220,7 @@ public class ImapStore extends Store {
* @param capabilities a list of the capabilities from the server
* @return a String for use in an IMAP ID message.
*/
/* package */ static String getImapId(Context context, String userName, String host,
@VisibleForTesting static String getImapId(Context context, String userName, String host,
String capabilities) {
// The first section is global to all IMAP connections, and generates the fixed
// values in any IMAP ID message
@ -280,7 +281,7 @@ public class ImapStore extends Store {
* @param networkOperator TelephonyManager.getNetworkOperatorName()
* @return the static (never changes) portion of the IMAP ID
*/
/* package */ static String makeCommonImapId(String packageName, String version,
@VisibleForTesting static String makeCommonImapId(String packageName, String version,
String codeName, String model, String id, String vendor, String networkOperator) {
// Before building up IMAP ID string, pre-filter the input strings for "legal" chars

View File

@ -0,0 +1,151 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.email;
import com.google.android.collect.Maps;
import android.content.SharedPreferences;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* A programmable mock content provider.
*/
public class MockSharedPreferences implements SharedPreferences, SharedPreferences.Editor {
private HashMap<String, Object> mValues = Maps.newHashMap();
private HashMap<String, Object> mTempValues = Maps.newHashMap();
@SuppressWarnings("unchecked")
public Editor edit() {
mTempValues = (HashMap<String, Object>) mValues.clone();
return this;
}
public boolean contains(String key) {
return mValues.containsKey(key);
}
public Map<String, ?> getAll() {
return new HashMap<String, Object>(mValues);
}
public boolean getBoolean(String key, boolean defValue) {
if (mValues.containsKey(key)) {
return ((Boolean)mValues.get(key)).booleanValue();
}
return defValue;
}
public float getFloat(String key, float defValue) {
if (mValues.containsKey(key)) {
return ((Float)mValues.get(key)).floatValue();
}
return defValue;
}
public int getInt(String key, int defValue) {
if (mValues.containsKey(key)) {
return ((Integer)mValues.get(key)).intValue();
}
return defValue;
}
public long getLong(String key, long defValue) {
if (mValues.containsKey(key)) {
return ((Long)mValues.get(key)).longValue();
}
return defValue;
}
public String getString(String key, String defValue) {
if (mValues.containsKey(key))
return (String)mValues.get(key);
return defValue;
}
@SuppressWarnings("unchecked")
public Set<String> getStringSet(String key, Set<String> defValues) {
if (mValues.containsKey(key)) {
return (Set<String>) mValues.get(key);
}
return defValues;
}
public void registerOnSharedPreferenceChangeListener(
OnSharedPreferenceChangeListener listener) {
throw new UnsupportedOperationException();
}
public void unregisterOnSharedPreferenceChangeListener(
OnSharedPreferenceChangeListener listener) {
throw new UnsupportedOperationException();
}
public Editor putBoolean(String key, boolean value) {
mTempValues.put(key, Boolean.valueOf(value));
return this;
}
public Editor putFloat(String key, float value) {
mTempValues.put(key, value);
return this;
}
public Editor putInt(String key, int value) {
mTempValues.put(key, value);
return this;
}
public Editor putLong(String key, long value) {
mTempValues.put(key, value);
return this;
}
public Editor putString(String key, String value) {
mTempValues.put(key, value);
return this;
}
public Editor putStringSet(String key, Set<String> values) {
mTempValues.put(key, values);
return this;
}
public Editor remove(String key) {
mTempValues.remove(key);
return this;
}
public Editor clear() {
mTempValues.clear();
return this;
}
@SuppressWarnings("unchecked")
public boolean commit() {
mValues = (HashMap<String, Object>) mTempValues.clone();
return true;
}
public void apply() {
commit();
}
}

View File

@ -16,6 +16,8 @@
package com.android.email.mail.store;
import com.android.email.DBTestHelper;
import com.android.email.MockSharedPreferences;
import com.android.email.MockVendorPolicy;
import com.android.email.VendorPolicyLoader;
import com.android.email.mail.Transport;
@ -48,6 +50,10 @@ import com.android.emailcommon.utility.Utility;
import org.apache.commons.io.IOUtils;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Bundle;
import android.test.InstrumentationTestCase;
import android.test.MoreAsserts;
@ -96,16 +102,49 @@ public class ImapStoreUnitTests extends InstrumentationTestCase {
private Folder mCopyToFolder;
private Message[] mCopyMessages;
/**
* A wrapper to provide a wrapper to a Context which has already been mocked.
* This allows additional methods to delegate to the original, real context, in cases
* where the mocked behavior is insufficient.
*/
private class SecondaryMockContext extends ContextWrapper {
private final Context mUnderlying;
public SecondaryMockContext(Context mocked, Context underlying) {
super(mocked);
mUnderlying = underlying;
}
// TODO: eliminate the need for these method.
@Override
public Context createPackageContext(String packageName, int flags)
throws NameNotFoundException {
return mUnderlying.createPackageContext(packageName, flags);
}
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return new MockSharedPreferences();
}
}
/**
* Setup code. We generate a lightweight ImapStore and ImapStore.ImapFolder.
*/
@Override
protected void setUp() throws Exception {
super.setUp();
// TODO: this should really use a mock context.
mTestContext = getInstrumentation().getTargetContext();
// Use the target's (i.e. the Email application) context
TempDirectory.setTempDirectory(getInstrumentation().getTargetContext());
Context realContext = getInstrumentation().getTargetContext();
ImapStore.sImapId = ImapStore.makeCommonImapId(realContext.getPackageName(),
Build.VERSION.RELEASE, Build.VERSION.CODENAME,
Build.MODEL, Build.ID, Build.MANUFACTURER,
"FakeNetworkOperator");
mTestContext = new SecondaryMockContext(
DBTestHelper.ProviderContextSetupHelper.getProviderContext(realContext),
realContext);
MockVendorPolicy.inject(mTestContext);
TempDirectory.setTempDirectory(mTestContext);
// These are needed so we can get at the inner classes
HostAuth testAuth = new HostAuth();