Как правильно смоделировать Пикассо в модульных тестах? - PullRequest
0 голосов
/ 02 июля 2018

Поскольку я пытаюсь провести следующий простой тест докладчика

public class NewsPresenterTest {
private static List<News> NEWS_HEADLINES;

@Mock
private NewsRepository mNewsRepository;

@Mock
private Picasso mPicassoClient;

@Mock
private ChromeTabsWrapper mChromeTabsWrapper;

@Mock
private NewsContract.View mNewsView;

@Captor
private ArgumentCaptor<NewsDataSource.LoadNewsCallback> mLoadNewsCallbackCaptor;

private NewsPresenter mNewsPresenter;

@Before
public void setupNewsPresenter() {
    // inject the mocks
    MockitoAnnotations.initMocks(this);

    mNewsPresenter = new NewsPresenter(mNewsRepository, new CompositeDisposable(), mPicassoClient, mChromeTabsWrapper);
    mNewsPresenter.subscribe(mNewsView);

    NEWS_HEADLINES = Lists.newArrayList(...);
}

@Test
public void loadHeadlinesNewsFromRepositoryAndLoadIntoView(){
          // verify certain behavior 
    }
}

Кажется, я не умею издеваться mPicassoClient, в результате получаю следующее исключение:

java.lang.ExceptionInInitializerError
at sun.reflect.GeneratedSerializationConstructorAccessor3.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
...more 
Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.os.Looper.getMainLooper(Looper.java)
at com.squareup.picasso.Picasso.<clinit>(Picasso.java:109)
... and more

Поскольку состояние стека, исключение происходит, когда инициируются mocks, чтобы быть более точным в этой строке MockitoAnnotations.initMocks(this);

Поэтому издеваться Picasso.class не удается. Что я делаю не так?

1 Ответ

0 голосов
/ 04 июля 2018

Класс Пикассо не принадлежит вашему докладчику. Переместите вызов Пикассо в свой фрагмент. Обратите внимание, что это не мешает покрытию тестом (менее явным образом):

Ранее:

newsRepository.getNews(date) 
   .subscribe(news ->
      Picasso.loadImage(news.getImageUrl()))

Рефакторинг:

newsRepository.getNews(date)
    .subscribe(news ->
        view.loadImage(news.getImageUrl()))

Где view - это вид из модели / вида / презентатора, реализованный вашей деятельностью или фрагментом. Внутри вашего фрагмента или действия:

@Override
public void loadImage(String url) {
    Picasso.loadImage(url);
}
...