【问题标题】:How to mock Picasso in unit tests in Android?如何在 Android 的单元测试中模拟毕加索?
【发布时间】:2017-02-02 08:55:10
【问题描述】:

我有使用毕加索库的代码。

 @Inject
 public RegistrationPresenter(UserData userData, Picasso picasso) {
    this.userData = userData;
    this.picasso = picasso;
 }

 @Override
 public void attachView(RegistrationView view) {
    super.attachView(view);
    view.toggleKeyboardButton(false);
    view.showFirstName(userData.getFirstName());
    view.showLastName(userData.getLastName());
    view.showEmail(userData.getEmail());
    setImage();
 }

 private void setImage() {
    String url = String.format(IMAGE_URL, userData.getId());
    String tag = String.format(JPG_EXT, userData.getId());
    picasso
            .load(url)
            .tag(tag)
            .into(new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    //some actions
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {
                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {
                }

            });
}

在我的演示者中,我通过 Dagger2 提供毕加索

@Provides
@Singleton
Picasso providesPicasso() {
    return Picasso.with(context);
}

在我的测试中,我使用的是 Robolectric 和 Mockito,所以我模拟了 Picasso 并将其传递给演示者的构造函数

@Mock
Picasso picasso;

@Before
public void setUp() {
    super.setUp();
    MockitoAnnotations.initMocks(this);
    mockData = new UserData();
    mockData.setFirstName("Name");
    mockData.setLastName("LastName");
    mockData.setEmail("example@gmail.com");
    mockData.setId("123456");

    File mockCacheDir = mock(File.class);
    Context mockAppContext = mock(Context.class);
    when(mockContext.getApplicationContext()).thenReturn(mockAppContext);
    when(mockContext.getApplicationContext().getCacheDir()).thenReturn(mockCacheDir);
    when(view.getContext()).thenReturn(mockContext);
    presenter = new RegistrationPresenter(mockData, picasso);
}

@Test
public void testAttachView() {
    presenter.attachView(view); //fails here
    verify(view).toggleKeyboardButton(false);
    verify(view).showFirstName(mockData.getFirstName());
    verify(view).showLastName(mockData.getLastName());
    verify(view).showEmail(mockData.getEmail());
}

当我运行我的测试时,它失败并出现异常

java.lang.NullPointerException
at com.squareup.picasso.Utils.createDefaultCacheDir(Utils.java:257)
at com.squareup.picasso.OkHttpDownloader.<init>(OkHttpDownloader.java:45)
at com.squareup.picasso.Utils$OkHttpLoaderCreator.create(Utils.java:424)
at com.squareup.picasso.Utils.createDefaultDownloader(Utils.java:250)
at com.squareup.picasso.Picasso$Builder.build(Picasso.java:832)
at com.squareup.picasso.Picasso.with(Picasso.java:662)

什么是模仿毕加索的正确方法?

【问题讨论】:

  • 你能告诉我们失败的单元测试吗?如果没有看到它,我会怀疑问题在于您从未为 Picasso 模拟设置任何行为。 Mocks 不使用被模拟类的真实方法,因此默认情况下它们只会返回 null。
  • @Pox 谢谢,已更新

标签: android unit-testing junit mockito picasso


【解决方案1】:

Don't mock File. 您的测试很可能失败,因为需要真正的File 实现。而是使用TemporaryFolder 规则:

@Rule
public TemporaryFolder folder = new TemporaryFolder();

@Before
public void setUp() {
  // ...
  when(mockContext.getApplicationContext().getCacheDir()).thenReturn(folder.newFolder()));
  // ...
 }

【讨论】:

  • 现在 NPE 失败 picasso .load(url) .tag(tag)
  • 请您为新的 NPE 创建一个新的 Stackoverflow 问题。这让每个人都更容易专注于特定问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 2017-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-19
  • 1970-01-01
相关资源
最近更新 更多