如何使用 OkHttpClient MockWebSever 返回图像/字节 []?

ASP*_*ASP 4 java android-library retrofit mockwebserver okhttp3

我正在开发一个 android 库项目,我需要从 REST 服务下载 PNG 图像,将其转换为 aBitmap并使用此库将其返回给应用程序。所以,我们有一个 REST web 服务,它返回一个 png 图像的字节数。我们使用Retrofitwith调用此服务rxJava。在我下面accessRemoteComm.getImage()的代码中,在 Observable 上进行了从 aResponseBodyBitmapa 内部的加载和转换.map。图像在应用程序中加载良好。我现在想对该方法进行单元测试,但我很难MockWebServer首先交付图像。在OnError不断调用:

java.lang.RuntimeException: Method decodeStream in android.graphics.BitmapFactory not mocked. See http://g.co/androidstudio/not-mocked for details.

这是我到目前为止:

改造界面:

@GET("webapi/user/{ID}/image")
Observable<ResponseBody> getVehicleImage(
        @Path("ID") @NonNull final String id,
        @Query("width") @NonNull final int width,
        @Query("height") @NonNull final int height,
        @Query("view") @NonNull final ImageView view
);
Run Code Online (Sandbox Code Playgroud)

getImage() 方法:

public Observable<Bitmap> getVehicleImage(@NonNull String id, @NonNull Integer width, @NonNull Integer height, @NonNull ImageView view) {
    return service.getImage(id, width, height, view).map(new Func1<ResponseBody, Bitmap>() {
        @Override
        public Bitmap call(ResponseBody responseBody) {
            BufferedInputStream isr = new BufferedInputStream(responseBody.byteStream());
            return BitmapFactory.decodeStream(isr);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

我的测试方法:

@Test
public void testGetVehicleImage() throws Exception {

    String path = basePathForImages + "vehicleTestImage.png";

    Source pngSource = Okio.source(new File(path));

    BufferedSource bufferedSrc = Okio.buffer(pngSource);

    server.enqueue(new MockResponse()
            .setResponseCode(200)
            .setHeader("Content-Type", "image/png")
            .setBody(bufferedSrc.buffer()));

    Subscriber<Bitmap> subscriber = new Subscriber<Bitmap>() {
        @Override
        public void onCompleted() {
            Log.d("OnComplete");
        }

        @Override
        public void onError(Throwable e) {
             Log.d(e.toString());
             //java.lang.RuntimeException: 
             //Method decodeStream in android.graphics.BitmapFactory not mocked.
        }

        @Override
        public void onNext(Bitmap bitmap) {
            Log.d("Yeeee");
        }
    };

    Observable<Bitmap> observable = accessRemoteCommVehicle.getVehicleImage("abc", 0, 0, VehicleImageView.FRONT);

    observable.toBlocking().subscribe(subscriber);
}
Run Code Online (Sandbox Code Playgroud)

我很确定,我没有bufferedSource正确设置。但是我在 SO 或网络上找不到任何显示MockResponsewith a Bufferas body用法的资源。这是部分,任何帮助表示赞赏。我该如何正确设置?

顺便提一句。如果您对如何进行测试有任何其他建议,请告诉我!

谢谢!

Mic*_*upo 5

我目前正在将它与 MockWebServer 一起使用并且似乎可以工作,但可能会使用一些里程。如果您尝试并反馈您的结果,将对社区有益。

         import okio.Buffer;
         private final static String TAG = "MYCLASS";
         public static String extPathToPngFile = Environment.getExternalStorageDirectory().getPath() + "/some-icon.png";

         Buffer responseBody = getBinaryFileAsBuffer(extPathToPngFile);

                             ... context removed for brevity ...

         new MockResponse().setResponseCode(200).addHeader("Content-Type:image/png").setBody(responseBody);

        //Buffer wrap a binary file to return with a mock.
        public static Buffer getBinaryFileAsBuffer(String path) throws IOException {
                        File file = new File(path);
                        byte[] fileData = FileUtils.readFileToByteArray(file);
                        Buffer buf = new Buffer();
                        buf.write(fileData);
                        Log.d(TAG, "BUFFER SIZE FOR "+path+" IS:" + buf.size());
                        return buf;
                    }
Run Code Online (Sandbox Code Playgroud)


小智 1

android.graphics.BitmapFactory是Android SDK的一部分,因此它在设备/模拟器上可用。如果您在主机(编译代码的地方)上运行单元测试,则 Android SDK 类在该环境中不可用。从错误来看,您使用 Mockito 来模拟对 SDK 的调用,但未模拟 debugStream 方法。

有几种方法可以解决这个问题:

  1. 使用Roboelectric ( http://robolectric.org/ ),它允许您调用主机上的 Android 框架方法。
  2. 让您的单元测试成为Android 测试(仪表测试),这意味着它将在模拟器/设备上运行。更多信息请参见:https ://developer.android.com/training/testing/unit-testing/instrumented-unit-tests