From df3cf9652e813421e91cb4c4511f372754eefa84 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Tue, 1 Jul 2014 22:40:19 -0400 Subject: [PATCH] More ugly unit testing... --- MinimalBible/build.gradle | 7 +- .../org/bspeice/minimalbible/Injectable.java | 12 +++ .../bspeice/minimalbible/MinimalBible.java | 9 +- .../minimalbible/MinimalBibleModules.java | 8 ++ MinimalBible/src/test/AndroidManifest.xml | 19 ---- .../minimalbible/test/MinimalBibleTest.java | 85 +++++----------- .../test/MinimalBibleTestMockable.java | 28 ++++++ .../downloader/BookListFragmentTest.java | 98 +++++++++++++++---- 8 files changed, 156 insertions(+), 110 deletions(-) create mode 100644 MinimalBible/src/main/java/org/bspeice/minimalbible/Injectable.java delete mode 100644 MinimalBible/src/test/AndroidManifest.xml create mode 100644 MinimalBible/src/test/java/org/bspeice/minimalbible/test/MinimalBibleTestMockable.java diff --git a/MinimalBible/build.gradle b/MinimalBible/build.gradle index 04250e6..c22b3df 100644 --- a/MinimalBible/build.gradle +++ b/MinimalBible/build.gradle @@ -52,12 +52,7 @@ android { } // Move the tests to tests/java, tests/res, etc... - androidTest { - manifest.srcFile 'src/test/AndroidManifest.xml' - java.srcDirs = ['src/test/java'] - resources.srcDirs = ['src/test/res'] - assets.srcDirs = ['src/test/assets'] - } + androidTest.setRoot('src/test') // Move the build types to build-types/ // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... diff --git a/MinimalBible/src/main/java/org/bspeice/minimalbible/Injectable.java b/MinimalBible/src/main/java/org/bspeice/minimalbible/Injectable.java new file mode 100644 index 0000000..9efe628 --- /dev/null +++ b/MinimalBible/src/main/java/org/bspeice/minimalbible/Injectable.java @@ -0,0 +1,12 @@ +package org.bspeice.minimalbible; + +/** + * Massive shout-out to vovkab for this idea. + */ +public interface Injectable { + + public Object[] getModules(); + + public void inject(Object o); + +} diff --git a/MinimalBible/src/main/java/org/bspeice/minimalbible/MinimalBible.java b/MinimalBible/src/main/java/org/bspeice/minimalbible/MinimalBible.java index 42a5d65..09eb633 100644 --- a/MinimalBible/src/main/java/org/bspeice/minimalbible/MinimalBible.java +++ b/MinimalBible/src/main/java/org/bspeice/minimalbible/MinimalBible.java @@ -10,7 +10,7 @@ import java.io.File; import dagger.ObjectGraph; -public class MinimalBible extends Application { +public class MinimalBible extends Application implements Injectable { /** * The graph used by Dagger to track dependencies @@ -71,13 +71,14 @@ public class MinimalBible extends Application { public ObjectGraph getObjGraph() { if (graph == null) { - graph = ObjectGraph.create(MinimalBibleModules.class); + graph = ObjectGraph.create(getModules()); } return graph; } - public void plusObjGraph(Object... modules) { - graph = graph.plus(modules); + @Override + public Object[] getModules() { + return MinimalBibleModules.list(); } /** diff --git a/MinimalBible/src/main/java/org/bspeice/minimalbible/MinimalBibleModules.java b/MinimalBible/src/main/java/org/bspeice/minimalbible/MinimalBibleModules.java index 346a598..574e5f1 100644 --- a/MinimalBible/src/main/java/org/bspeice/minimalbible/MinimalBibleModules.java +++ b/MinimalBible/src/main/java/org/bspeice/minimalbible/MinimalBibleModules.java @@ -16,4 +16,12 @@ import dagger.Module; } ) public class MinimalBibleModules { + + private MinimalBibleModules() {} + + public static Object[] list() { + return new Object[] { + MinimalBibleModules.class + }; + } } diff --git a/MinimalBible/src/test/AndroidManifest.xml b/MinimalBible/src/test/AndroidManifest.xml deleted file mode 100644 index cce9973..0000000 --- a/MinimalBible/src/test/AndroidManifest.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - diff --git a/MinimalBible/src/test/java/org/bspeice/minimalbible/test/MinimalBibleTest.java b/MinimalBible/src/test/java/org/bspeice/minimalbible/test/MinimalBibleTest.java index 0f54763..4175386 100644 --- a/MinimalBible/src/test/java/org/bspeice/minimalbible/test/MinimalBibleTest.java +++ b/MinimalBible/src/test/java/org/bspeice/minimalbible/test/MinimalBibleTest.java @@ -1,75 +1,38 @@ package org.bspeice.minimalbible.test; +import android.app.Application; import android.content.Context; +import android.os.Build; import org.bspeice.minimalbible.MinimalBible; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + import dagger.ObjectGraph; -public class MinimalBibleTest extends MinimalBible { - - /** - * The graph used by Dagger to track dependencies - */ - private ObjectGraph graph; - - /** - * A singleton reference to the Application currently being run. - * Used mostly so we have a fixed point to get the App Context from - */ - private static MinimalBibleTest instance; - - private String TAG = "MinimalBibleTest"; - - /** - * Create the application, and persist the application Context - */ - public MinimalBibleTest() { - instance = this; - } - - /** - * Get the Application Context. Please note, all attempts to get the App Context should come - * through here, and please be sure that the Application won't satisfy what you need. - * @return The Application Context - */ - public static Context getAppContext() { - return instance; +public class MinimalBibleTest extends Application { + public MinimalBibleTest(Context ctx) { + attachBaseContext(ctx); } - /** - * Get the Application, rather than just the Application Context. You likely should be using - * this, rather than {@link #getAppContext()} - * @return The MinimalBible {@link android.app.Application} object - */ - public static MinimalBibleTest getApplication() { - return instance; - } - - /** - * Create the {@link android.app.Application}. Responsible for building and - * holding on to the master ObjectGraph. - */ @Override - public void onCreate() { - super.onCreate(); - //TODO: Is this necessary? - inject(this); - } - - /** - * Inject a Dagger object - * @param o The object to be injected - */ - @Override - public void inject(Object o) { - getObjGraph().inject(o); - } - - public ObjectGraph getObjGraph() { - if (graph == null) { - graph = ObjectGraph.create(MinimalBibleModulesTest.class); + public void attachBaseContext(Context base) { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) { + super.attachBaseContext(base); + } else { + try { + Class applicationClass = Application.class; + Method attach = applicationClass.getDeclaredMethod("attach", Context.class); + attach.setAccessible(true); + attach.invoke(this, base); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } } - return graph; } } diff --git a/MinimalBible/src/test/java/org/bspeice/minimalbible/test/MinimalBibleTestMockable.java b/MinimalBible/src/test/java/org/bspeice/minimalbible/test/MinimalBibleTestMockable.java new file mode 100644 index 0000000..045b104 --- /dev/null +++ b/MinimalBible/src/test/java/org/bspeice/minimalbible/test/MinimalBibleTestMockable.java @@ -0,0 +1,28 @@ +package org.bspeice.minimalbible.test; + +import android.content.Context; + +import org.bspeice.minimalbible.Injectable; + +import dagger.ObjectGraph; + +/** + * Created by bspeice on 6/27/14. + */ +public abstract class MinimalBibleTestMockable extends MinimalBibleTest implements Injectable { + + private ObjectGraph mObjectGraph; + + public MinimalBibleTestMockable(Context context) { + super(context); + mObjectGraph = ObjectGraph.create(getModules()); + } + + @Override + public abstract Object[] getModules(); + + @Override + public void inject(Object o) { + mObjectGraph.inject(o); + } +} diff --git a/MinimalBible/src/test/java/org/bspeice/minimalbible/test/activities/downloader/BookListFragmentTest.java b/MinimalBible/src/test/java/org/bspeice/minimalbible/test/activities/downloader/BookListFragmentTest.java index 5a69512..9f9b3d6 100644 --- a/MinimalBible/src/test/java/org/bspeice/minimalbible/test/activities/downloader/BookListFragmentTest.java +++ b/MinimalBible/src/test/java/org/bspeice/minimalbible/test/activities/downloader/BookListFragmentTest.java @@ -1,47 +1,88 @@ package org.bspeice.minimalbible.test.activities.downloader; +import android.app.Application; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; -import android.test.ActivityInstrumentationTestCase2; +import android.test.ActivityUnitTestCase; import org.bspeice.minimalbible.MinimalBible; -import org.bspeice.minimalbible.test.MinimalBibleModulesTest; import org.bspeice.minimalbible.activities.downloader.BookListFragment; import org.bspeice.minimalbible.activities.downloader.DownloadActivity; import org.bspeice.minimalbible.activities.downloader.DownloadPrefs; +import org.bspeice.minimalbible.test.MinimalBibleModulesTest; +import org.bspeice.minimalbible.test.MinimalBibleTest; +import org.bspeice.minimalbible.test.MinimalBibleTestMockable; import org.crosswire.jsword.book.BookCategory; import java.util.concurrent.CountDownLatch; +import javax.inject.Inject; + import dagger.Module; +import dagger.Provides; import de.devland.esperandro.Esperandro; /** * Created by bspeice on 6/23/14. */ -public class BookListFragmentTest extends ActivityInstrumentationTestCase2 { +public class BookListFragmentTest extends ActivityUnitTestCase { + private static Class activityUnderTest = DownloadActivity.class; @Module(injects = TestDialogDisplayedIfFirstTimeFragment.class, - addsTo = MinimalBibleModulesTest.class + addsTo = MinimalBibleModulesTest.class, + overrides = true ) - protected static class BookListFragmentTestModule{} - - public BookListFragmentTest() { - super(DownloadActivity.class); + protected static class BookListFragmentTestModule{ + @Provides + DownloadPrefs providePrefs() { + return Esperandro.getPreferences(DownloadPrefs.class, + MinimalBible.getApplication()); + } } + public BookListFragmentTest() { + super(activityUnderTest); + } + + @Inject DownloadPrefs downloadPrefs; FragmentManager mFragmentManager; + private Application mApplication; + private Context mContext; + + @Override public void setUp() throws Exception { super.setUp(); - mFragmentManager = getActivity().getSupportFragmentManager(); - assertNotNull(mFragmentManager); + // Set 'dexmaker.dexcache' system property, otherwise sometimes it is null and test will crash + // System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext().getCacheDir().getPath()); + + mContext = new ContextWrapper(getInstrumentation().getTargetContext()) { + @Override + public Context getApplicationContext() { + return mApplication; + } + }; + + mApplication = new MinimalBibleTestMockable(mContext) { + @Override public Object[] getModules() { + return new Object[]{new BookListFragmentTestModule()}; + } + }; + + setApplication(mApplication); } + @Override + public void tearDown() throws Exception { + super.tearDown(); + } public F startFragment(F fragment) { try { @@ -68,15 +109,19 @@ public class BookListFragmentTest extends ActivityInstrumentationTestCase2