Process crashes during creation of RoboGuice injector, if there is a mocked instance in any module
Solution 1:
Unfortunately, if there's an issue with the setup steps for RoboGuice & unit testing, you can get this sort of error. No magic short answer, but rather a set of steps to follow exactly.
BTW, you're using RoboGuice 1.1 - AbstractAndroidModule & RoboUnitTest no longer exist in RoboGuice 2.0. RoboGuice 1.1 is deprecated, so best overall solution is to move to newest version according to these instructions Upgrading to 2.0.
However, just in case you're attached to RoboGuice 1.1, here's some steps to follow:
- Don't have inconsistent generated code/build files after refactoring/changing package names etc. Delete generated code, do a Clean & Build, even recreate a new project and copy source files in.
- Have your app code in one project (RoboGuice dependent, Instrumentation/RoboUnitTestCase/AndroidMock independent). You app code project has within lib: guice-2.0-no_aop.jar and roboguice-1.1.2.jar.
- Have your unit test code in another project that references it (RoboGuice independent, Instrumentation/RoboUnitTestCase/AndroidMock independent). Instructions here Before You Get Started. Your test code project has within lib: AndroidMockGenerator.jar.
-
In your app project, your App + Module classes look something like this:
package com.mypackage; import android.app.Instrumentation; import android.content.Context; public class MyApplication extends roboguice.application.RoboApplication { static MyModule myModule; // this constructor usually called by app public MyApplication(Context context) { super(); attachBaseContext(context); } // This constructor called by unit tests. This is unfortunately small amount of // 'abstraction leakage' of unit test needs into app code. public MyApplication(Instrumentation instrumentation) { super(); attachBaseContext(instrumentation.getContext()); } public static void setModule(MyModule module) { MyApplication.myModule = module; } public static MyModule getModule() { return MyApplication.myModule; } }
And
package com.mypackage; public class MyModule extends roboguice.config.AbstractAndroidModule { // this will be injected protected UsefulObject myUsefulInstance; public void setUsefulObject(UsefulObject usefulInstance) { this.myUsefulInstance = usefulInstance; } public UsefulObject getUsefulObject() { return this.myUsefulInstance; } @Override protected void configure() { bind(UsefulObject.class).toInstance(myUsefulInstance); }
}
-
In your test project, your test case class looks something like this:
import android.test.suitebuilder.annotation.LargeTest; import com.mypackage.MyApplication; import com.mypackage.MyModule; import com.mypackage.UsefulObject; //import com.mypackage.UsefulObjectSimpleImplementation; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import com.google.android.testing.mocking.AndroidMock; import roboguice.test.RoboUnitTestCase; public class TestMyModule extends RoboUnitTestCase<MyApplication> { @Override protected void setUp() throws Exception { UsefulObject instance = // new UsefulObjectSimpleImplementation(); AndroidMock.createNiceMock(UsefulObject.class); MyModule mockModule = new MyModule(); mockModule.setUsefulObject(instance); MyApplication.setModule(mockModule); super.setUp(); } // Make sure you use one of the @*Test annotations AND begin // your testcase's name with "test" @MediumTest public void test01() { AndroidMock.expect(MyApplication.getModule().getUsefulObject(). simpleMethod()).andStubReturn("Hello!"); }
}
Ensure that for the test project, the AndroidManifest.xml file has the following entry:
<instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.mypackage" android:label="Tests for com.mypackage"/>
- Before running your test, ensure your emulator is started and is running healthily, by running a different, simple "Hello World" app first. When this succeeds, then run your app. Lastly, run your test project.
Should work after this. Best of luck & let me know!