我正在尝试为Android应用编写单元测试,该应用使用dagger进行ViewModel注入。我似乎没有为JUnitTest注射工作。当我使用@Mock注入gapiService时,Retrofit返回null调用请求:
final MutableLiveData<GissuesResponse> lData = new MutableLiveData<>();
Call<List<Issue>> callRequest = gapiService.getIssues(owner, repo);
我的整个项目位于http://github.com/CodingWords/Gissues
不确定如何在JUnitTest中正确设置ViewModel以进行注入。谢谢!
Here is my JUnitTest
import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelProviders;
import com.codingwords.sobrien.gissues.api.GAPIService;
import com.codingwords.sobrien.gissues.model.SearchIssuesModel;
import com.codingwords.sobrien.gissues.repo.IssueRepository;
import com.codingwords.sobrien.gissues.vm.GissuesViewModel;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import javax.inject.Inject;
public class GissuesUnitTest {
@Mock //Mock annotation tells Mockito to give a mocked object
GissuesScreen gissuesScreen;
@Mock
GAPIService gapiService;
//class that is being tested
@Inject
ViewModelProvider.Factory viewModelFactory;
IssueRepository gissuesRepo;
GissuesViewModel gissuesViewModel;
final String dummyOwner = "ethereum";
final String dummyRepo = "solidity";
@Before
public void setupGissuesViewModel(){
//this function will be called before all tests are run
// call this function to init all objects annotated with @mock
MockitoAnnotations.initMocks(this);
gissuesRepo = new IssueRepository();
gissuesRepo.setGapiService(gapiService);
gissuesViewModel = new GissuesViewModel(gissuesRepo);
gissuesViewModel.setGissuesScreen(gissuesScreen);
SearchIssuesModel sim = new SearchIssuesModel();
gissuesViewModel.setSearchModel(sim);
//we create an instance of the class to be tested by passing the mocked objec
}
@Test
public void requestIssuesWithEmptyOwner_showsOwnerError(){
gissuesViewModel.getSearchModel().setOwner("");
gissuesViewModel.pullIssues();
//use mockito to verify that the showOwnerError() method is called in the screen object
Mockito.verify(gissuesScreen).showOwnerError();
}
@Test
public void requestIssuesWithEmptyRepo_showsRepoError(){
gissuesViewModel.getSearchModel().setOwner("ethereum");
gissuesViewModel.getSearchModel().setRepo("");
gissuesViewModel.pullIssues();
Mockito.verify(gissuesScreen).showRepoError();
}
@Test
public void requestIssuesWithEmptyList_showsIssuesNotFound(){
gissuesViewModel.getSearchModel().setOwner("ethereum");
gissuesViewModel.getSearchModel().setRepo("ethereum");
gissuesViewModel.pullIssues();
Mockito.verify(gissuesScreen).showIssuesNotFound();
}
}
这是IssueRepo
public class IssueRepository implements IssueRepo {
@Inject
public IssueRepository() {
}
@Inject
GAPIService gapiService;
@Override
public LiveData<GissuesResponse> receiveIssues(String owner, String repo) {
final MutableLiveData<GissuesResponse> lData = new MutableLiveData<>();
// callRequest is returned as null because gapiService was mock object?
Call<List<Issue>> callRequest = gapiService.getIssues(owner, repo);
callRequest.enqueue(new Callback<List<Issue>>() {
@Override
public void onResponse(Call<List<Issue>> call, Response<List<Issue>> response) {
lData.setValue(new GissuesResponse(response.body()));
}
@Override
public void onFailure(Call<List<Issue>> call, Throwable t) {
lData.setValue(new GissuesResponse(t));
}
});
return lData;
}
public GAPIService getGapiService() {
return gapiService;
}
public void setGapiService(GAPIService gapiService) {
this.gapiService = gapiService;
}
}
这是视图模型
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MediatorLiveData;
import android.arch.lifecycle.ViewModel;
import android.support.annotation.NonNull;
import com.codingwords.sobrien.gissues.GissuesScreen;
import com.codingwords.sobrien.gissues.entity.GissuesResponse;
import com.codingwords.sobrien.gissues.model.SearchIssuesModel;
import com.codingwords.sobrien.gissues.repo.IssueRepo;
import javax.inject.Inject;
/**
* Created by Administrator on 2/19/2018.
*/
public class GissuesViewModel extends ViewModel {
private IssueRepo issueRepository;
private MediatorLiveData<GissuesResponse> gapiResponse;
private SearchIssuesModel searchModel;
private GissuesScreen gissuesScreen;
@Inject
public GissuesViewModel(IssueRepo repository) {
this.issueRepository = repository;
this.gapiResponse = new MediatorLiveData<GissuesResponse>();
}
public MediatorLiveData<GissuesResponse> getGapiResponse() {
return gapiResponse;
}
public void pullIssues(){
if (getSearchModel() != null){
if ((getSearchModel().getOwner() == null) || (getSearchModel().getOwner().length() < 2)){
gissuesScreen.showOwnerError();
} else if ((getSearchModel().getRepo() == null) || (getSearchModel().getRepo().length() < 2)) {
gissuesScreen.showRepoError();
} else {
pullIssues(getSearchModel().getOwner(), getSearchModel().getRepo());
}
}
}
public void pullIssues(@NonNull String user, String repo) {
LiveData<GissuesResponse> issuesSource = issueRepository.receiveIssues(user, repo);
gapiResponse.addSource(
issuesSource,
gapiResponse -> {
if (this.gapiResponse.hasActiveObservers()) {
this.gapiResponse.removeSource(issuesSource);
}
this.gapiResponse.setValue(gapiResponse);
}
);
}
public SearchIssuesModel getSearchModel() {
return searchModel;
}
public void setSearchModel(SearchIssuesModel searchModel) {
this.searchModel = searchModel;
}
public GissuesScreen getGissuesScreen() {
return gissuesScreen;
}
public void setGissuesScreen(GissuesScreen gissuesScreen) {
this.gissuesScreen = gissuesScreen;
}
}