Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create custom shadows in robolectric 3.0?

I need to mock some custom class (create for it a shadow). I have already read on http://robolectric.org/custom-shadows/ how to do this.

so, i have some class:

public class MyClass {

  public static int regularMethod() { return 1; }
}

I create a shadow:

@Implements(MyClass.class)
public class MyShadowClass {

  @Implementation
  public static int regularMethod() { return 2; }
}

And i set the shadow in Test-class:

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, shadows={MyShadowClass.class})
public class MyTest {

  @Test
  public void testShadow() {
      assertEquals(2, MyClass.regularMethod());
  }
}

But the shadow is not used.

java.lang.AssertionError: 
Expected :2
Actual   :1

How to make any custom shadow visible for RobolectricGradleTestRunner?

I have already tried:

  1. http://www.codinguser.com/2015/06/how-to-create-shadow-classes-in-robolectric-3/
  2. https://github.com/jiahaoliuliu/RobolectricSample/blob/master/app-tests/src/main/java/com/jiahaoliuliu/robolectricsample/RobolectricGradleTestRunner.java
  3. Mock native method with a Robolectric Custom shadow class

but i get various compilation errors, such as

  • InstrumentingClassLoaderConfig not found
  • Setup not found

how to use custom shadows correctly in robolectric 3.0?

like image 295
yital9 Avatar asked Aug 10 '15 13:08

yital9


1 Answers

Custom shadows should be avoided and must be a last ditch resort. It should only be used if you cannot do much refactor in your code which is preventing you from running your tests like a native method call. It's better to mock the object of that class or spy using powermock or mockito than custom shadow it. If it's a static method, then use powermock.

In our project, we had a class which had some native methods and it was the config class used everywhere in the app. So we moved the native methods to another class and shadowed that. Those native methods were failing the test cases.

Anyways here's how you can custom shadow in robolectric 3.0:

Create a custom test runner that extends RobolectricGradleTestRunner:

public class CustomRobolectricTestRunner extends RobolectricGradleTestRunner {


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

public InstrumentationConfiguration createClassLoaderConfig() {
    InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();
    builder.addInstrumentedPackage("com.yourClassPackage");
    return builder.build();
}

Make sure that that the package doesn't contain any test cases that you are running using robolectric.

like image 130
Kanishk Avatar answered Oct 21 '22 22:10

Kanishk