Search code examples
androidunit-testingjunitactionbarsherlockrobolectric

Android unit testing with Robolectrics and ActionBarSherlock


I'm using Robolectric to test my LoginActivity class. I'm using ActionBarSherlock and Robolectric tests fail on getSupportActionBar() line. Here's my code and trace.

LoginActivity.java

import org.json.JSONException;
import org.json.JSONObject;
import com.actionbarsherlock.app.SherlockActivity;

public class LoginActivity extends SherlockActivity {
        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        ...
...
..
 }

LoginActivityTest.java

import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
..
.
@RunWith(RobolectricTestRunner.class)
public class LoginActivityTest {

     private LoginActivity activity;
     @Before
    public void setUp() throws Exception
    {
        }

   @Test @Config(reportSdk = 10)
    public void shouldActivityCreated() throws Exception {
           activity = Robolectric.buildActivity(LoginActivity.class).create().get();
           assertNotNull(activity);
    }
}

When I try to JUnit test, I got failure with trace :

java.lang.IllegalStateException: You must use Theme.Sherlock, Theme.Sherlock.Light, Theme.Sherlock.Light.DarkActionBar, or a derivative.
    at com.actionbarsherlock.internal.ActionBarSherlockCompat.generateLayout(ActionBarSherlockCompat.java:1003)
    at com.actionbarsherlock.internal.ActionBarSherlockCompat.installDecor(ActionBarSherlockCompat.java:915)
    at com.actionbarsherlock.internal.ActionBarSherlockCompat.initActionBar(ActionBarSherlockCompat.java:138)
    at com.actionbarsherlock.internal.ActionBarSherlockCompat.getActionBar(ActionBarSherlockCompat.java:128)
    at com.actionbarsherlock.app.SherlockActivity.getSupportActionBar(SherlockActivity.java:37)
    at auth.LoginActivity.onCreate(LoginActivity.java:92)
    at android.app.Activity.performCreate(Activity.java:5008)
    at org.fest.reflect.method.Invoker.invoke(Invoker.java:112)
    at org.robolectric.util.ActivityController$1.run(ActivityController.java:116)
    at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:256)
    at org.robolectric.util.ActivityController.create(ActivityController.java:111)
    at org.robolectric.util.ActivityController.create(ActivityController.java:123)
    at LoginActivityTest.shouldActivityCreated(LoginActivityTest.java:85)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:234)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:175)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

After research, I found this : https://gist.github.com/marsucsb/6059760 I created these 3 classes, and write necessary registration & unregistration codes in my setup function in my test class, I cannot set contentview for shadowed mActivity : shadowOf(mActivity).setContentView(contentView);

I'm using Eclipse and Robolectric 2.2-jar-with-dependencies

Do you have any idea to skip this ActionBarSherlock error while testing? Thanks.


Solution

  • As I mentioned in a different answer, here is a Gist that takes @Xian's Gist with a suggestion from marsucsb and modifies it to work with Robolectric 2.2+

    To answer this particular question, shadowOf(mActivity) is no longer available in Robolectric 2.2+, so mActivity.getWindow().setContentView(view) should be used instead of shadowOf(mActivity).setContentView(view)