在 Android 中使用假 http 响应测试 Activity

Test Activity with fake http response in Android

我有一个 Activity 用于 registration.The Activity 获取用户的个人资料,例如电子邮件和密码,然后将这些值上传到 server.The 服务器 return成功后将这些值设为 Activity,以便 Activity 将它们保存到 SharedPreferences。
我的问题是,如何编写一个 return 假响应的测试,以便 Activity 不必与真实服务器交互,并检查值是否已准确保存到首选项?

这是我的 Activity:

public class RegisterActivity extends AppCompatActivity implements RegisterRestClientUsage.RegisterCallback{
    private RegisterRestClientUsage registerRestClientUsage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        registerRestClientUsage = new RegisterRestClientUsage(this);
        //...
    }
    public void onClick(View view){
        String email = emailEditText.getText().toString();
        String password = passwordEditText.getText().toString();
        registerRestClientUsage.registerToServer(email,password);
    }
    @Override
    public void registerSuccess(String token, String email) {

        //Save those values to SharedPreferences

        finish();
    }

    @Override
    public void registerFail() {
        finish();
    }
}

RegisterClientUsage.class

public class RegisterRestClientUsage {
    private RegisterCallback callback;
    public interface RegisterCallback{
        void registerSuccess(String token,String email);
        void registerFail();
    }

    public RegisterRestClientUsage(RegisterCallback r){
        callback = r;
    }
    public void registerToServer(String email,String password){
            RequestParams params = new RequestParams();
            params.put("email", email);
            params.put("password", password);

            BaseRestClient.post("api/users/sign_up", params, new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                    try {
                        JSONObject responseJson = new JSONObject(new String(responseBody));
                        returnToken = responseJson.optString("token");
                        JSONObject userJson = responseJson.optJSONObject("user");
                        returnEmail = userJson.optString("email");
                        callback.registerSuccess(returnToken,returnEmail);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                    callback.registerFail();
                }
            });
    }
}  

BaseRestClient.class

public class BaseRestClient {
    public static final String BASE_URL =  "https://my.api.com/";
    private static AsyncHttpClient client = new AsyncHttpClient();

    public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
        client.post(getAbsoluteUrl(url), params, responseHandler);
    }

}

由于 RegisterRestClientUsage 嵌入在 RegisterActivity 中,我找不到将我的假服务器注入 Activity 的好方法。

感谢@geek90 的帮助,我终于想出了一个 solution.I 用另一个控制器(RegisterController.class)包装我真正的 api 实现(RegisterRestClientUsage.class):

public class RegisterController{

    private RegisterServer serverSide;

    public RegisterController(RegisterServer r){
        serverSide = r;
    }

    public void registerToServer(String email,String password) {
        RequestParams params = new RequestParams();
        params.put("email", email);
        params.put("password", password);
        serverSide.registerToServer(params);
    }
} 

RegisterRestClientUsage.class实现RegisterServer接口:

public interface RegisterServer{
    void registerToServer(String email,String  pwd);
}

并且在RegisterActivityonCreate()方法中,用参数RegisterRestClientUsage构建控制器

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_register);
    registerController = new RegisterController(new RegisterRestClientUsage(this));
    //...
}

在这种情况下,我可以将 api 的假实现存根到控制器中进行测试:

@RunWith(AndroidJUnit4.class)
public class RegisterActivityTest {
    FakeRegisterRestClientUsage fakeRegisterRestClientUsage;
    @Rule
    public ActivityTestRule<RegisterActivity> activityTestRule = new ActivityTestRule<>(RegisterActivity.class);
    @Before
    public void setUp(){
        Activity activity = activityTestRule.getActivity();
        fakeRegisterRestClientUsage = new FakeRegisterRestClientUsage((RegisterRestClientUsage.RegisterCallback) activity);
        registerController = new RegisterController(fakeRegisterRestClientUsage);
    }
    @Test
    public void savePreferenceAfterRegistration(){
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                registerController.registerToServer("FAKE_NAME", "FAKE_BIRTH", "FAKE_EMAIL", "FAKE_GENDER", "FAKE_PWD", file);
            }
        });
        waitForActionsToComplete();

        //Assert that the data has been properly save to the preferences
    }
    public void waitForActionsToComplete(){
        CountDownLatch signal = fakeRegisterRestClientUsage.signal;
        try {
            signal.await(30, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}