Ran*_*ngh 5 android mockito retrofit2
如果我的问题看起来重复,请原谅我,但我没有得到如何测试改造API调用的信息。 在应用程序级别的build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile("com.android.support.test.espresso:espresso-core:$rootProject.ext.expressoVersion", {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion"
compile "com.jakewharton:butterknife:$rootProject.ext.butterKnifeVersion"
annotationProcessor "com.jakewharton:butterknife-compiler:$rootProject.ext.butterKnifeVersion"
// Dependencies for local unit tests
testCompile "junit:junit:$rootProject.ext.junitVersion"
testCompile "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
testCompile "org.hamcrest:hamcrest-all:$rootProject.ext.hamcrestVersion"
testCompile "org.powermock:powermock-module-junit4:$rootProject.ext.powerMockito"
testCompile "org.powermock:powermock-api-mockito:$rootProject.ext.powerMockito"
compile "com.android.support.test.espresso:espresso-idling-resource:$rootProject.ext.espressoVersion"
// retrofit, gson
compile "com.google.code.gson:gson:$rootProject.ext.gsonVersion"
compile "com.squareup.retrofit2:retrofit:$rootProject.ext.retrofitVersion"
compile "com.squareup.retrofit2:converter-gson:$rootProject.ext.retrofitVersion"
}
Run Code Online (Sandbox Code Playgroud)
项目级别的build.gradle具有此额外内容
//在一个地方定义版本
ext {
// Sdk and tools
minSdkVersion = 15
targetSdkVersion = 25
compileSdkVersion = 25
buildToolsVersion = '25.0.2'
supportLibraryVersion = '23.4.0'
junitVersion = '4.12'
mockitoVersion = '1.10.19'
powerMockito = '1.6.2'
hamcrestVersion = '1.3'
runnerVersion = '0.5'
rulesVersion = '0.5'
espressoVersion = '2.2.2'
gsonVersion = '2.6.2'
retrofitVersion = '2.0.2'
butterKnifeVersion = '8.5.1'
expressoVersion = '2.2.2'
}
Run Code Online (Sandbox Code Playgroud)
主要活动
public class MainActivity extends AppCompatActivity implements MainView {
@BindView(R.id.textViewApiData)
TextView mTextViewApiData;
@BindView(R.id.progressBarLoading)
ProgressBar mProgressBarLoading;
private MainPresenter mMainPresenter;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initializeComponents();
}
private void initializeComponents() {
mMainPresenter = new MainPresenter(this);
mMainPresenter.presentDataFromApi();
}
@Override
public void onResponseReceived(final String response) {
mTextViewApiData.setText(response);
}
@Override
public void onErrorReceived(final String message) {
mTextViewApiData.setText(message);
}
@Override
public void showProgressDialog(final boolean enableProgressDialog) {
mProgressBarLoading.setVisibility(enableProgressDialog ? View.VISIBLE : View.GONE);
}
}
Run Code Online (Sandbox Code Playgroud)
主视图
public interface MainView {
void onResponseReceived(String response);
void onErrorReceived(String message);
void showProgressDialog(boolean enableProgressDialog);
}
Run Code Online (Sandbox Code Playgroud)
ApiClient
public class ApiClient {
private static Retrofit sRetrofit;
public static Retrofit getInstance() {
if (sRetrofit == null) {
sRetrofit = new Retrofit.Builder()
.baseUrl(Constants.Urls.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return sRetrofit;
}
}
Run Code Online (Sandbox Code Playgroud)
主持人
public class MainPresenter {
private final MainView mMainView;
private final Call<List<UserResponse>> mCallListUserResponse;
public MainPresenter(final MainView mainView) {
this.mMainView = mainView;
final ApiInterface apiInterface = ApiClient.getInstance().create(ApiInterface.class);
mCallListUserResponse = apiInterface.getUsers();
}
public void presentDataFromApi() {
mMainView.showProgressDialog(true);
mCallListUserResponse.enqueue(new Callback<List<UserResponse>>() {
@Override
public void onResponse(final Call<List<UserResponse>> call,
final Response<List<UserResponse>> response) {
mMainView.onResponseReceived(Constants.DummyData.SUCCESS);
mMainView.showProgressDialog(false);
}
@Override
public void onFailure(final Call<List<UserResponse>> call, final Throwable t) {
mMainView.onErrorReceived(Constants.DummyData.ERROR);
mMainView.showProgressDialog(false);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
Api接口
public interface ApiInterface {
@GET(Constants.Urls.USERS)
Call<List<UserResponse>> getUsers();
}
Run Code Online (Sandbox Code Playgroud)
常数
public class Constants {
public class Urls {
public static final String BASE_URL = "https://jsonplaceholder.typicode.com";
public static final String USERS = "/users";
}
}
Run Code Online (Sandbox Code Playgroud)
这是我正在尝试做的,但是没有用。由于我已经评论了最后三行中的3条,因此测试用例将暂时通过。取消注释这些行后即可查看错误。
测试用例
public class MainPresenterTest {
@InjectMocks
private MainPresenter mMainPresenter;
@Mock
private MainView mMockMainView;
@Mock
private Call<List<UserResponse>> mUserResponseCall;
@Captor
private ArgumentCaptor<Callback<List<UserResponse>>> mArgumentCaptorUserResponse;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void presentDataFromApiTest() throws Exception {
mMainPresenter.presentDataFromApi();
verify(mMockMainView).showProgressDialog(true);
// verify(mUserResponseCall).enqueue(mArgumentCaptorUserResponse.capture());
// verify(mMockMainView).onResponseReceived(Constants.DummyData.SUCCESS);
// verify(mMockMainView).showProgressDialog(false);
}
}
Run Code Online (Sandbox Code Playgroud)
日志记录
Wanted but not invoked:
mUserResponseCall.enqueue(
<Capturing argument>
);
-> at com.example.ranaranvijaysingh.testingdemo.presenters.MainPresenterTest.presentDataFromApiTest(MainPresenterTest.java:69)
Actually, there were zero interactions with this mock.
Run Code Online (Sandbox Code Playgroud)
小智 2
您的代码在语法上看起来是正确的。但是,我怀疑 @InjectMock 无法将模拟对象注入到最终实例变量中。当您调用 mMainPresenter.presentDataFromApi() 时,以下变量可能被用作真实实例:
private final Call<List<UserResponse>> mCallListUserResponse;
Run Code Online (Sandbox Code Playgroud)
您应该尝试将模拟变量手动注入此类并分配给 mCallListUserResponse 以便能够从mockito实例化中获得收益。
可能值得尝试以下步骤:
将 MainPresenter 中的变量 mCallListUserResponse 设置为非最终变量。
在 MainPresenter 类中添加一个方法,如下所示:
void setUserResponseCall(Call> userResponse){ mCallListUserResponse = userResponse; }
现在在测试类中执行以下操作:
修改您的测试如下
@Test
public void presentDataFromApiTest() throws Exception {
//Set mock instance of the user response
mMainPresenter.setUserResponseCall(mUserResponseCall);
//real object call to presentDataFromApi();
mMainPresenter.presentDataFromApi();
verify(mMockMainView).showProgressDialog(true);
verify(mUserResponseCall).enqueue(mArgumentCaptorUserResponse.capture());
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你。
| 归档时间: |
|
| 查看次数: |
4883 次 |
| 最近记录: |