robolectricrobolectric-gradle-plugin

Robolectric 3.2.2 get instance of shadow classes?


I have implemented the MVP on my android application and am looking at creating test scripts to test basic behavior functionality. Long story short, is there a way to get an instance of the shadow object I've created?

I would like to be able to tell the mock model object what to return in a method, for example, when getGender() is called, return Male, but for another method, getGender() will return Female.

I've found away to do it now but I was lucky with the design of the model. This is the test:

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 22, shadows = { GenderPreferenceInteractorShaddow.class })
public class newPreferenceBehaviourTest {


    @Test
    public void clickingLogin_shouldStartLoginActivity() {
        NewPreferenceMobileActivityTest activity = Robolectric.setupActivity(NewPreferenceMobileActivityTest.class);
        activity.setGender(Gender.MALE);

        activity.findViewById(R.id.femaleImageButton).performClick();
        activity.findViewById(R.id.positiveButton).performClick();
    }


}

The model constructor takes a context as a construct, so I can create a test activity, which extends the activity I want to test.

public class NewPreferenceMobileActivityTest extends NewPreferenceMobileActivity {
    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    private Gender gender;
}

This new model will contain a getter and setter for the value I want to change. In the constructor of the shadow object, I can cast the context as test activity and then the getter of the mocked model can return what I want:

@Implements(GenderPreferenceInteractor.class)
public class GenderPreferenceInteractorShaddow   {


    private  NewPreferenceMobileActivityTest newPreferenceMobileActivityTest;
    private GenderPreferenceMVP.onFinished onFinished;

    public void __constructor__ (Context context) {
        newPreferenceMobileActivityTest = (NewPreferenceMobileActivityTest) context;
    }

    @Implementation
    public void saveGender(Gender gender) {
        onFinished.onSaveSuccess(true);
    }

    @Implementation
    public Gender getGender()
    {
        return newPreferenceMobileActivityTest.getGender();
    }

}

EDIT --> Not possible but there is a work around. In the GenderPreferenceInteractorShaddow class, pass a reference back to NewPreferenceMobileActivityTest class and we have a reference to the class.

public void __constructor__ (Context context) {
        newPreferenceMobileActivityTest = (NewPreferenceMobileActivityTest) context;
        newPreferenceMobileActivityTest.setGenderPreferenceInteractorShaddow(this);
    }


public class NewPreferenceMobileActivityTest extends NewPreferenceMobileActivity {

    private GenderPreferenceInteractorShaddow genderPreferenceInteractorShaddow;

    public ladenzeile.android.newPreference.GenderPreferenceInteractorShaddow getGenderPreferenceInteractorShaddow() {
        return genderPreferenceInteractorShaddow;
    }

    public void setGenderPreferenceInteractorShaddow(ladenzeile.android.newPreference.GenderPreferenceInteractorShaddow genderPreferenceInteractorShaddow) {
        this.genderPreferenceInteractorShaddow = genderPreferenceInteractorShaddow;

A downside to this is that you need to set the Gender variable to a default value


Solution

  • You could use ShadowExtractor like this:

    GenderPreferenceInteractorShaddow shadowGender = (GenderPreferenceInteractorShaddow) ShadowExtractor.extract(genderPreferenceInteractor);