2

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

Killesk
  • 2,734
  • 3
  • 22
  • 29

1 Answers1

3

You could use ShadowExtractor like this:

GenderPreferenceInteractorShaddow shadowGender = (GenderPreferenceInteractorShaddow) ShadowExtractor.extract(genderPreferenceInteractor);
Steve C
  • 1,034
  • 10
  • 12
  • Hey Steve, I don't have a reference to the GenderPreferenceInteractor class, that instantiation is done in the fragment and I don't have access to that object. – Killesk Feb 28 '17 at 09:15
  • 1
    If you don't have access to the interactor you have to use a library such as Mockito to mock your interactor. For example : this https://medium.com/@Miqubel/testing-android-mvp-aa0de6e165e4#.aofbudlpr – Steve C Feb 28 '17 at 09:52