0

I want to use MockWebServer to mock the response of requests in my UI tests.

Every getting-started-guide or tutorial I found place the url in a custom MyApp extends Application class and make it available by public String getApiUrl {return "http://realUrl";}. In tests they create an MyTestApp extends MyApp and override @Override getApiUrl() {return "http://testurl";}.

The problem is that I define the url in a repository where I have no access to Application, so I cannot call getApplication.getApiUrl(). For this reason, I am looking for an alternative without extending Application.

One option that comes to my mind is to implement a function setUrl(String url) in the repository. Then I implement a class TestApplication extends Application and override onCreate() and call repository.setUrl("http://testurl"). However this bring testcode into my production code, which I would like to avoid.

My favorite solution would be to mock the repository or a simple constants class, so I can tell that class to simply return another url in tests.

Gerke
  • 926
  • 1
  • 10
  • 20

1 Answers1

1

For now I implemented the option I described in my question. For everyone who has the same problems, here is what I did:

My Repository:


public class PremixStationRepository {
    private static PremixStationRepository instance;

    private String premixStationIp = "http://10.17.13.221:5000";  // This is the not-test Ip


    public static PremixStationRepository getInstance() {
        if(instance == null) {
            instance = new PremixStationRepository();
        }
        return instance;
    }

    

    public void updatePremixStationStatus() {
        Callback callback = new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                // do whatever you wanna do in case of failure
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response {
             // do whatever you wanna do in case of success

            }
        };
        OkHttpManager.sendRequest(premixStationIp + "/whatever", callback);
    }

    // This method is used by TestApplicationClass to update the premix station ip
    public void setPremixStationIp(String premixStationIp) {
        this.premixStationIp = premixStationIp;
    }

}

My TestApplicationClass:

public class TestApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        PremixStationRepository.getInstance().setPremixStationIp("http:127.0.0.1:8080");
    }
}

Custom MockTestRunner

public class MockTestRunner extends AndroidJUnitRunner {
    @Override
    public void onCreate(Bundle arguments) {
        StrictMode.setThreadPolicy((new StrictMode.ThreadPolicy.Builder()).permitAll().build());
        super.onCreate(arguments);
    }

    @Override
    public Application newApplication(ClassLoader cl, String className, Context context) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        return super.newApplication(cl, SmartPremixTestApplication.class.getName(), context);
    }
}

Then change the Manifest file to use the custom MockTestRunner for instrumented tests as described in this tutorial: https://tech.okcupid.com/ui-tests-with-mockwebserver/. From that point, you can use the tutorial and the official documentations to continue

Gerke
  • 926
  • 1
  • 10
  • 20