Robolectric - the application has singlets in the configuration, causing problems with tests

I have currently inherited an Android application that has zero code coverage, and my first job is to get some unit tests written for it. So I decided to use it as an opportunity to learn Robolectric.

However, I run the initial problems, getting two simple dummy tests to run.

Here is my code in the test file:

@Config(constants = BuildConfig.class)
@RunWith(RobolectricGradleTestRunner.class)
public class SplashActivityTest {

private SplashActivity activity;

// @Before => JUnit 4 annotation that specifies this method should run before each test is run
// Useful to do setup for objects that are needed in the test
@Before
public void setup() {
    // Convenience method to run SplashActivity through the Activity Lifecycle methods:
    // onCreate(...) => onStart() => onPostCreate(...) => onResume()
    activity = Robolectric.setupActivity(SplashActivity.class);
}

// @Test => JUnit 4 annotation specifying this is a test to be run
// Checking that the UI gets setup correctly
@Test
public void dummy() {
  String test = "POP!";

    assertTrue("POP!",
            test.equals("POP!"));
}

@Test
public void dummyTwo() {

    String test = "POP!!";

    assertTrue("POP!!",
            test.equals("POP!!"));
}

}

The problem is that the action extends another class called baseactivity, and this class uses its own Application class.

In this custom application class, Picasso is created as a Singleton using the following code:

picasso = new Picasso.Builder(getApplicationContext()).downloader(new OkHttpDownloader(picassoClient)).build();
    Picasso.setSingletonInstance(picasso);

When I run the tests, I get the following error:

java.lang.IllegalStateException: Singleton .    com.squareup.picasso.Picasso.setSingletonInstance(Picasso.java:677)

, , , , . , , ? - ? Unit test, , , .

EDIT: "mock" Robolectric , , , .

, test/java :

public class TestMyApplication extends MyApplication
        implements TestLifecycleApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        initPicasso();
    }

    @Override
    protected void initPicasso() {
        //nothing to do
    }

    @Override public void beforeTest(Method method) {
    }

    @Override public void prepareTest(Object test) {
    }

    @Override public void afterTest(Method method) {
    }
}

, MyApplication, , @Override initPicasso, , , , , Picasso Singleton .

, , - Application , Robolectric , ?

:

@Config(constants = BuildConfig.class, application = TestMyApplication.class)

, , TestMyApplication, , Robolectric .

+4
2

, , RobolectricGradleTestRunner TestMyApplication.

public class TestRunner extends RobolectricGradleTestRunner {

    public TestRunner(final Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override
    protected Class<? extends TestLifecycle> getTestLifecycleClass() {
        return MyTestLifecycle.class;
    }

    public static class MyTestLifecycle extends DefaultTestLifecycle {
        @Override
        public Application createApplication(final Method method, final AndroidManifest appManifest, final Config appConfig) {
            // run tests under our TestApplication
            return new TestMyApplication();
        }
    }

}

TestMyApplication initPicasso:

@Override protected void initPicasso(){
        //do nothing
    }

Robolectric, , initPicasso MyApplication.java.

+4

Robolectric 3.4.2 :

public class MyApplication extends Application {

    protected void initPicasso() {
        // do Picasso initialization
    }

}

public class TestMyApplication extends MyApplication {

    @Override
    protected void initPicasso() {
        //nothing to do
    }

}

Config :

@Config(constants = BuildConfig.class, application = TestMyApplication.class)
+2

All Articles