Files
frameworks_base/test-runner/src/android/test/ProviderTestCase2.java
Paul Duffin 4ea70a23ea Modify android.test.runner to use new mock APIs
Previous change added some new public APIs to allow the
android.test.runner classes to be built against the public API stubs
rather than the internal classes. This change updates the
android.test.runner classes to use that new API.

This in turn is preparation for building an android.test.legacy library
that can be safely statically included in APKs.

Bug: 30188076
Test: make checkbuild

(cherry picked from commit 20af1df63f)

Merged-In: I302626abb7e048ef0c3169e9a5209b85f2f87d34
Change-Id: Ie05a17598fcabc1189cacc912c01a25782ebd29c
2018-02-06 13:38:44 +00:00

239 lines
9.6 KiB
Java

/*
* Copyright (C) 2007 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 android.test;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContext;
import android.test.mock.MockContentResolver;
import android.database.DatabaseUtils;
import java.io.File;
/**
* This test case class provides a framework for testing a single
* {@link ContentProvider} and for testing your app code with an
* isolated content provider. Instead of using the system map of
* providers that is based on the manifests of other applications, the test
* case creates its own internal map. It then uses this map to resolve providers
* given an authority. This allows you to inject test providers and to null out
* providers that you do not want to use.
* <p>
* This test case also sets up the following mock objects:
* </p>
* <ul>
* <li>
* An {@link android.test.IsolatedContext} that stubs out Context methods that might
* affect the rest of the running system, while allowing tests to do real file and
* database work.
* </li>
* <li>
* A {@link android.test.mock.MockContentResolver} that provides the functionality of a
* regular content resolver, but uses {@link IsolatedContext}. It stubs out
* {@link ContentResolver#notifyChange(Uri, ContentObserver, boolean)} to
* prevent the test from affecting the running system.
* </li>
* <li>
* An instance of the provider under test, running in an {@link IsolatedContext}.
* </li>
* </ul>
* <p>
* This framework is set up automatically by the base class' {@link #setUp()} method. If you
* override this method, you must call the super method as the first statement in
* your override.
* </p>
* <p>
* In order for their tests to be run, concrete subclasses must provide their own
* constructor with no arguments. This constructor must call
* {@link #ProviderTestCase2(Class, String)} as its first operation.
* </p>
* For more information on content provider testing, please see
* <a href="{@docRoot}tools/testing/contentprovider_testing.html">Content Provider Testing</a>.
*/
public abstract class ProviderTestCase2<T extends ContentProvider> extends AndroidTestCase {
Class<T> mProviderClass;
String mProviderAuthority;
private IsolatedContext mProviderContext;
private MockContentResolver mResolver;
private class MockContext2 extends MockContext {
@Override
public Resources getResources() {
return getContext().getResources();
}
@Override
public File getDir(String name, int mode) {
// name the directory so the directory will be separated from
// one created through the regular Context
return getContext().getDir("mockcontext2_" + name, mode);
}
@Override
public Context getApplicationContext() {
return this;
}
}
/**
* Constructor.
*
* @param providerClass The class name of the provider under test
* @param providerAuthority The provider's authority string
*/
public ProviderTestCase2(Class<T> providerClass, String providerAuthority) {
mProviderClass = providerClass;
mProviderAuthority = providerAuthority;
}
private T mProvider;
/**
* Returns the content provider created by this class in the {@link #setUp()} method.
* @return T An instance of the provider class given as a parameter to the test case class.
*/
public T getProvider() {
return mProvider;
}
/**
* Sets up the environment for the test fixture.
* <p>
* Creates a new
* {@link android.test.mock.MockContentResolver}, a new IsolatedContext
* that isolates the provider's file operations, and a new instance of
* the provider under test within the isolated environment.
* </p>
*
* @throws Exception
*/
@Override
protected void setUp() throws Exception {
super.setUp();
mResolver = new MockContentResolver();
final String filenamePrefix = "test.";
RenamingDelegatingContext targetContextWrapper = new
RenamingDelegatingContext(
new MockContext2(), // The context that most methods are
//delegated to
getContext(), // The context that file methods are delegated to
filenamePrefix);
mProviderContext = new IsolatedContext(mResolver, targetContextWrapper);
mProvider = createProviderForTest(mProviderContext, mProviderClass, mProviderAuthority);
mResolver.addProvider(mProviderAuthority, getProvider());
}
/**
* Creates and sets up a new instance of the provider.
*/
static <T extends ContentProvider> T createProviderForTest(
Context context, Class<T> providerClass, String authority)
throws IllegalAccessException, InstantiationException {
T instance = providerClass.newInstance();
ProviderInfo providerInfo = new ProviderInfo();
providerInfo.authority = authority;
MockContentProvider.attachInfoForTesting(instance, context, providerInfo);
return instance;
}
/**
* Tears down the environment for the test fixture.
* <p>
* Calls {@link android.content.ContentProvider#shutdown()} on the
* {@link android.content.ContentProvider} represented by mProvider.
*/
@Override
protected void tearDown() throws Exception {
mProvider.shutdown();
super.tearDown();
}
/**
* Gets the {@link MockContentResolver} created by this class during initialization. You
* must use the methods of this resolver to access the provider under test.
*
* @return A {@link MockContentResolver} instance.
*/
public MockContentResolver getMockContentResolver() {
return mResolver;
}
/**
* Gets the {@link IsolatedContext} created by this class during initialization.
* @return The {@link IsolatedContext} instance
*/
public IsolatedContext getMockContext() {
return mProviderContext;
}
/**
* <p>
* Creates a new content provider of the same type as that passed to the test case class,
* with an authority name set to the authority parameter, and using an SQLite database as
* the underlying data source. The SQL statement parameter is used to create the database.
* This method also creates a new {@link MockContentResolver} and adds the provider to it.
* </p>
* <p>
* Both the new provider and the new resolver are put into an {@link IsolatedContext}
* that uses the targetContext parameter for file operations and a {@link MockContext}
* for everything else. The IsolatedContext prepends the filenamePrefix parameter to
* file, database, and directory names.
* </p>
* <p>
* This is a convenience method for creating a "mock" provider that can contain test data.
* </p>
*
* @param targetContext The context to use as the basis of the IsolatedContext
* @param filenamePrefix A string that is prepended to file, database, and directory names
* @param providerClass The type of the provider being tested
* @param authority The authority string to associated with the test provider
* @param databaseName The name assigned to the database
* @param databaseVersion The version assigned to the database
* @param sql A string containing the SQL statements that are needed to create the desired
* database and its tables. The format is the same as that generated by the
* <a href="http://www.sqlite.org/sqlite.html">sqlite3</a> tool's <code>.dump</code> command.
* @return ContentResolver A new {@link MockContentResolver} linked to the provider
*
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static <T extends ContentProvider> ContentResolver newResolverWithContentProviderFromSql(
Context targetContext, String filenamePrefix, Class<T> providerClass, String authority,
String databaseName, int databaseVersion, String sql)
throws IllegalAccessException, InstantiationException {
MockContentResolver resolver = new MockContentResolver();
RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(
new MockContext(), // The context that most methods are delegated to
targetContext, // The context that file methods are delegated to
filenamePrefix);
Context context = new IsolatedContext(resolver, targetContextWrapper);
DatabaseUtils.createDbFromSqlStatements(context, databaseName, databaseVersion, sql);
T provider = createProviderForTest(context, providerClass, authority);
resolver.addProvider(authority, provider);
return resolver;
}
}