【发布时间】:2017-04-29 08:08:00
【问题描述】:
我正在使用 MVP 架构来构建我的应用程序。我的演示者调用 DataManager,它负责从网络或数据库获取数据。当我使用 RxJava 时,我在 Presenter 中订阅观察者并将适当的状态传递给 UI。我的服务层有 Android 上下文,它还会创建一个我自己类型的异常,它也引用了上下文。
if (isNetworkConnected()) {
final Call<ServiceResponse<AppVersion>> call = mService.getAppVersion();
try {
final Response<ServiceResponse<AppVersion>> response = call.execute();
if (response.isSuccessful()) {
final ServiceResponse<AppVersion> serviceResponse = response.body(); response.body();
if (serviceResponse.isSuccess()) {
subscriber.onNext(serviceResponse.getData());
} else {
subscriber.onError(new CustomException(mContext, response.code(), response.message(), serviceResponse.getErrorList()));
}
} else {
subscriber.onError(new CustomException(mContext, response.code(), response.message(), response.errorBody().string()));
}
} catch (IOException e) {
e.printStackTrace();
subscriber.onError(e);
} finally {
subscriber.onCompleted();
}
} else {
subscriber.onError(new NoInternetException());
}
我的 CustomException 还会在 Crashlytics 中记录崩溃。当我对这段代码进行单元测试时,我从 Crashlytics 中得到了一个未初始化的异常。所以我需要模拟Crashlytics的静态方法logException。但是我应该如何传递这个模拟对象,因为演示者不接受这个对象?
public staticErrorType getErrorType(Throwable throwable) {
//409: Not handled as its a conflict response code and comes in PUT/POST
if (throwable instanceof IOException) {
return ErrorType.NO_INTERNET;
} else if (throwable instanceof CustomException) {
final int errorCode = ((CustomException) throwable).mErrorCode;
if (errorCode == 404) {
return ErrorType.NOT_FOUND;
} else if (errorCode == 401) {
return ErrorType.UNAUTORISED;
} else if (errorCode == 403) {
return ErrorType.FORBIDDEN;
} else if (errorCode == 500 || errorCode == 502) {
return ErrorType.NO_SERVER_TRY_AGAIN;
} else if (errorCode > 500 && errorCode < 599) {
return ErrorType.NO_SERVER_TRY_LATER;
} else if (errorCode == 1000) {
return ErrorType.NO_COURSE_ENROLLED;
} else if (errorCode == 1001) {
return ErrorType.NO_COURSE_STARTED;
}
}
if (throwable != null) {
Crashlytics.logException(throwable);
}
return ErrorType.SOME_THING_WENT_WRONG;
}
【问题讨论】:
-
这听起来像是您的课程设计的问题。 CustomException 本身不应记录到 Crashlyrics。相反,订阅者应有责任在必要时进行登录。
-
@DavidRawson 所以自定义异常应该由其他人订阅,或者我应该将自定义记录器类传递给异常,它将异常记录到任何平台,比如 Crashlytics 并模拟它以进行测试?
-
感谢您的编辑 - 这使问题更加清晰。一个好的解决方案是使用包装类来包装 Crashlytics 中的静态方法。然后将包装类作为订阅者的依赖项传入。见this answer
-
@DavidRawson CustomException的静态方法应该怎么做,它应该是方法本身的参数,因为静态方法不能被删除。当这个 throwable 被发送到 Presenter 时,我需要知道我通过这个方法调用得到的 Presenter 中的错误类型,并且据此我需要告诉视图进行渲染。所以我可以将这个 CustomLogger 类从演示者传递给静态方法,还是应该遵循任何其他设计模式?
-
我会更新我的答案
标签: android unit-testing mocking crashlytics