mockito 如何在Android中模拟Base64?

ff29svar  于 2022-11-08  发布在  Android
关注(0)|答案(5)|浏览(270)

我正在为一个使用android.util.Base64的类编写单元测试,但遇到以下错误:

java.lang.RuntimeException: Method encode in android.util.Base64 not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.util.Base64.encode(Base64.java)

这是使用encode()方法的程式码:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// [write some data to the stream]
byte[] base64Bytes = Base64.encode(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);

现在我明白了我不能在单元测试中使用Android库类。但是我如何正确地模拟Base64,以便为我的类编写正确的单元测试呢?

js4nwp54

js4nwp541#

我来晚了,但也许这会对某些人有所帮助。对于JUnit,您可以在没有任何第三方库的情况下模拟类。Base64.java在app/src/test/java/android/util中创建一个文件www.example.com,其内容如下:

package android.util; 

public class Base64 {

    public static String encodeToString(byte[] input, int flags) {
        return java.util.Base64.getEncoder().encodeToString(input);
    }

    public static byte[] decode(String str, int flags) {
        return java.util.Base64.getDecoder().decode(str);
    }

    // add other methods if required...
}

xiozqbni

xiozqbni2#

基于Nkosi和Christopher的评论,我找到了一个解决方案。我使用PowerMock来模拟Base64的静态方法:

PowerMockito.mockStatic(Base64.class);
when(Base64.encode(any(), anyInt())).thenAnswer(invocation -> java.util.Base64.getEncoder().encode((byte[]) invocation.getArguments()[0]));
when(Base64.decode(anyString(), anyInt())).thenAnswer(invocation -> java.util.Base64.getMimeDecoder().decode((String) invocation.getArguments()[0]));

在我的build.gradle中,我必须添加:

testImplementation "org.powermock:powermock-module-junit4:1.7.4"
testImplementation "org.powermock:powermock-api-mockito2:1.7.4"

请注意,并不是每个版本的Powermock都能与每个版本的Mockito兼容。我在这里使用的版本应该能与Mockito 2.8.0-2.8.9兼容,我没有遇到任何问题。但是,对Mockito 2的支持仍处于试验阶段。在项目的wiki上有一个表格详细列出了兼容的版本。

jfgube3f

jfgube3f3#

使用Mockito的新版本,您还可以模拟静态方法。不再需要powermockito:
在Gradle中:

testImplementation "org.mockito:mockito-inline:4.0.0"
testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"

在Kotlin:

mockStatic(Base64::class.java)
`when`(Base64.encode(any(), anyInt())).thenAnswer { invocation ->
    java.util.Base64.getMimeEncoder().encode(invocation.arguments[0] as ByteArray)
}
`when`(Base64.decode(anyString(), anyInt())).thenAnswer { invocation ->
    java.util.Base64.getMimeDecoder().decode(invocation.arguments[0] as String)
}
z2acfund

z2acfund4#

对于Kotlin,您可以使用:

package android.util

import java.util.Base64

public object Base64 {
    @JvmStatic
    public fun encodeToString(input: ByteArray?, flags: Int): String {
        return Base64.getEncoder().encodeToString(input)
    }

    @JvmStatic
    public fun decode(str: String?, flags: Int): ByteArray {
        return Base64.getDecoder().decode(str)
    }
}
9njqaruj

9njqaruj5#

如果您运行的测试调用了Android SDK中未模拟的API,您将收到一条错误消息,指出此方法未被模拟。这是因为用于运行单元测试的android.jar文件不包含任何实际代码(这些API仅由设备上的Android系统映像提供)。

相关问题