Android Studio 2.3
我有以下方法我想我的模型類的內部測試:嘲笑我的測試類中的方法
public class RecipeListModelImp implements RecipeListModelContract {
private Subscription subscription;
private RecipesAPI recipesAPI;
private RecipeSchedulers recipeSchedulers;
@Inject
public RecipeListModelImp(@NonNull RecipesAPI recipesAPI, @NonNull RecipeSchedulers recipeSchedulers) {
this.recipesAPI = Preconditions.checkNotNull(recipesAPI);
this.recipeSchedulers = Preconditions.checkNotNull(recipeSchedulers);
}
@Override
public void getRecipesFromAPI(final RecipeGetAllListener recipeGetAllListener) {
subscription = recipesAPI.getAllRecipes()
.subscribeOn(recipeSchedulers.getBackgroundScheduler())
.observeOn(recipeSchedulers.getUIScheduler())
.subscribe(new Subscriber<List<Recipe>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
recipeGetAllListener.onRecipeGetAllFailure(e.getMessage());
}
@Override
public void onNext(List<Recipe> recipe) {
recipeGetAllListener.onRecipeGetAllSuccess(recipe);
}
});
}
@Override
public void shutdown() {
if(subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
}
在我的測試類我測試這樣的:
public class RecipeListModelImpTest {
@Mock Subscription subscription;
@Mock RecipesAPI recipesAPI;
@Mock RecipeListModelContract.RecipeGetAllListener recipeGetAllListener;
@Mock List<Recipe> recipes;
@Inject RecipeSchedulers recipeSchedulers;
private RecipeListModelContract recipeListModel;
@Before
public void setup() {
TestBusbyComponent testBusbyComponent = DaggerTestBusbyComponent.builder()
.mockRecipeSchedulersModule(new MockRecipeSchedulersModule())
.build();
testBusbyComponent.inject(RecipeListModelImpTest.this);
MockitoAnnotations.initMocks(RecipeListModelImpTest.this);
recipeListModel = new RecipeListModelImp(recipesAPI, recipeSchedulers);
}
@Test(expected = NullPointerException.class)
public void testShouldThrowExceptionOnNullParameter() {
recipeListModel = new RecipeListModelImp(null, null);
}
@Test
public void testRecipeListModelShouldNotBeNull() {
assertNotNull(recipeListModel);
}
@Test
public void testShouldGetRecipesFromAPI() {
when(recipesAPI.getAllRecipes()).thenReturn(Observable.just(recipes));
recipeListModel.getRecipesFromAPI(recipeGetAllListener);
verify(recipesAPI, times(1)).getAllRecipes();
verify(recipeGetAllListener, times(1)).onRecipeGetAllSuccess(recipes);
verify(recipeGetAllListener, never()).onRecipeGetAllFailure(anyString());
}
@Test
public void testShouldFailToGetRecipesFromAPI() {
when(recipesAPI.getAllRecipes())
.thenReturn(Observable.<List<Recipe>>error(
new Throwable(new RuntimeException("Failed to get recipes"))));
recipeListModel.getRecipesFromAPI(recipeGetAllListener);
verify(recipesAPI, times(1)).getAllRecipes();
verify(recipeGetAllListener, times(1)).onRecipeGetAllFailure(anyString());
verify(recipeGetAllListener, never()).onRecipeGetAllSuccess(recipes);
}
@Test
public void testShouldShutdown() {
when(subscription.isUnsubscribed()).thenReturn(false);
final Field subscriptionField;
try {
subscriptionField = recipeListModel.getClass().getDeclaredField("subscription");
subscriptionField.setAccessible(true);
subscriptionField.set(recipeListModel, subscription);
} catch(NoSuchFieldException e) {
e.printStackTrace();
}
catch(IllegalAccessException e) {
e.printStackTrace();
}
recipeListModel.shutdown();
verify(subscription, times(1)).unsubscribe();
}
}
但是,問題是我的模型類中的訂閱始終爲空,因此永遠不會進入if blook。有什麼方法可以用Mockito或spys來測試嗎?
非常感謝您的任何建議,
當然。做你所做的事情,但一定要將模擬訂閱注入RecipeListModel。如果不瞭解代碼,就很難提供建議。 –