androidunit-testingmockingrobolectricrobolectric-gradle-plugin

Robolectric 3: Shadow custom class


i'm using Robolectric 3 and i'm trying to shadow a custom class like so:

public class Yakir {

    public int foo() {
        return 1;
    }


}

@Implements(Yakir.class)
public class TestYakir {

    @Implementation
    public int foo() {
        return 2;
    }


}

And I've read on other answers and posts that Robolectric shadows SDK classes and for custom classes I need to do something special Like so:

public class RoboServiceRunner extends RobolectricGradleTestRunner {

public RoboServiceRunner(Class<?> klass) throws InitializationError {
    super(klass);
}


@Override
public Config getConfig(Method method) {
    Config config = super.getConfig(method);
    config.shadows();
    return config;
}


@Override
protected ShadowMap createShadowMap(){
    ShadowMap shadowMap = super.createShadowMap();
    shadowMap = shadowMap.newBuilder().addShadowClass(ServiceTest.TestYakir.class).build();
    return shadowMap;
}


}

So what you see here is code to add the new class to the shadowMap. I'm also aware if the Shadows class but I cant find what to do with it.

So the output for this test :

@RunWith(RoboServiceRunner.class)
@Config(constants = BuildConfig.class, shadows =   {ServiceTest.TestYakir.class})

 public class ServiceTest {

@Test
@Config(constants = BuildConfig.class, shadows = {ServiceTest.TestYakir.class})
public void testService() {

    assertEquals(2, new Yakir().foo());

}

is:

junit.framework.AssertionFailedError: Expected :2 Actual :1

Thanks!


Solution

  • So after more digging around the web I found a simple solution that worked for me.

    All you need to do is to override a method in the class that extends

    RobolectricGradleTestRunner

    the method is:

    @Override
    public InstrumentationConfiguration createClassLoaderConfig() {
        InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();
        builder.addInstrumentedClass(YourCustomShadowClass.class.getName());
        return builder.build();    }
    

    And that's it! Test passed with flying colors :)