如何使用mock()和spy()测试静态方法

Let*_*rIt 8 junit android unit-testing mockito powermockito

代码部分中的下面发布的方法包含一个静态方法,即"with()".我想测试下面的代码,所以我编写了这个方法的测试,如测试部分所示.

我尝试使用"spy()"和"mock()"测试方法,但测试失败了alwyas.

请让我知道如何测试方法返回void?

 public RequestCreator requestCreatorFromUrl(String picUrl) {
    return Picasso.with(mCtx).load(picUrl);
}
Run Code Online (Sandbox Code Playgroud)

测试:

public class ValidationTest {
@Mock
private Context mCtx = null;
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();

@Before
public void setUp() throws Exception {
    mCtx = Mockito.mock(Context.class);
    Assert.assertNotNull("Context is not null", mCtx);
}

 @Test
public void whenRequestCreatorFromUrlTest() throws Exception {
    Picasso picasso = Picasso.with(mCtx);
    Picasso spyPicasso = spy(picasso);
    Uri mockUri = mock(Uri.class);
    RequestCreator requestCreator = Picasso.with(mCtx).load(mockUri);
    RequestCreator spyRequestCreator = spy(requestCreator);

    doReturn(spyRequestCreator).when(spyPicasso.load(mockUri));
    //when(spyPicasso.load(mockUri)).thenReturn(spyRequestCreator);
    RequestCreator actual = spyPicasso.load(mockUri);

    Assert.assertEquals(requestCreator, actual);
}
Run Code Online (Sandbox Code Playgroud)

azi*_*ian 6

通常情况下,如果你最终使用PowerMock,这是一个很好的迹象,你最有可能是错误的方式.

如果不是直接引用Picasso,你创建一个组件,其职责是加载图像,让我们说类ImageLoader.这会给你什么?

  • 关注点分离:如果明天你决定搬到Glide,你不应该改变你所使用的每一个班级Picasso,你只需改变实施ImageLoader.其他组件对这些更改并不了解,因为它们依赖于抽象,而不依赖于实现

  • Seam:这将允许您轻松地模拟依赖项以执行单元测试

这将是我们的抽象:


    class ImageLoader {
        RequestCreator load(String url);
    }

我们来提供一个实现:


    class ImageLoaderImpl implements ImageLoader {

        private final Picasso picasso;

        public ImageLoader(Context context) {
            this.picasso = Picasso.with(context);
        }

        @Overrides
        public RequestCreator load(String url) {
            return picasso.load(url);
        }
    }

现在,无论何时需要Picasso使用,都可以在组件中使用ImageLoader.

因此,您的方法变为:


    public RequestCreator requestCreatorFromUrl(String picUrl) {
        return imageLoader.load(picUrl);
    }

然后你的测试看起来像这样:


    @Test
    public void test() {
        ImageLoader imageLoader = Mockito.mock(ImageLoader.class);
        RequestCreator expected = Mockito.mock(RequestCreator.class);
        String TEST_URL = "https://www.some.url/img.jpg";

        when(imageLoader.load(TEST_URL)).thenReturn(expexted);

        RequestCreator actual = clazzToTest.requestCreatorFromUrl(TEST_URL);

        assertEquals(expected, actual);
    }

没有嘲笑static方法,没有PowerMock必要.