2

有什么方法可以使用任何 Mocking Framework 在 Android 中模拟静态函数。Mockito 可以模拟类,但不足以模拟静态函数。

任何帮助将不胜感激。

提前致谢

4

3 回答 3

2

模拟通过使用面向对象、继承等概念来工作......

基本上是通过覆盖看起来像真实对象的对象/实例中的某些方法和行为,因为它们是这些真实对象的子类。

换句话说,模拟部分来自于实例上的重写方法。

无法覆盖静态方法 (afaik)。

因此,模拟静态调用并不容易(如果可能的话)。


编辑 - 我错了......

事实证明,我在上面的陈述中是错误的,这是不可能的。

我应该在这个网站上搜索重复的问题。有关在某些情况下声称可以为您执行此操作的框架的一些链接,请参见下文。由于它们使用字节码,我不确定它们能否在 Android (ymmv) 上正常工作。


(感谢 Rohit 强迫我重新评估我的信念)

于 2013-02-05T09:06:32.013 回答
0

请改用这个:https ://bintray.com/linkedin/maven/dexmaker-mockito-inline-extended

它帮助我成功地模拟了 Android Instrumented Tests 中的静态方法,但请注意,此功能需要在至少具有 Android P的设备上运行。

这是我所做的:

  • 替换androidTestImplementation 'org.mockito:mockito-android:2.28.0'androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito-inline-extended:2.28.0'

  • 然后像这样模拟静态方法:

    static class StaticTrojan {
        static String staticOpen() { return "horse"; }
    }
    
    @Test
    public void testStubbingStaticMethod() {
        MockitoSession session = mockitoSession().spyStatic(StaticTrojan.class).startMocking();
        try {
            when(StaticTrojan.staticOpen()).thenReturn("soldiers");
            assertEquals("soldiers", StaticTrojan.staticOpen());
        } finally {
            session.finishMocking();
        }
    
        // Once the session is finished, all stubbings are reset
        assertEquals("horse", StaticTrojan.staticOpen());
    }
    
于 2020-09-25T02:50:24.143 回答
0

如果您使用Kotlin,那么要模拟静态函数,您可以连接mockk库项目:

androidTestImplementation "io.mockk:mockk-android:1.12.0"

然后,如果您的测试位于应用程序模块中,则需要将一个添加AndroidManifest.xmlandroidTest目录。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="you.application.package">

    <application
        android:debuggable="true"
        android:extractNativeLibs="true" />
</manifest>

然后您可以使用以下代码模拟静态函数:

import io.mockk.every
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import org.junit.Assert.assertEquals
import org.junit.Test

class TestMockingStaticFunction {

    object StaticTrojan {

        @JvmStatic
        fun staticOpen(): String {
            return "horse"
        }
    }

    @Test
    fun testMockingStaticFunction() {
        assertEquals("horse", StaticTrojan.staticOpen())

        mockkStatic(StaticTrojan::staticOpen)
        val mockScope = every { StaticTrojan.staticOpen() } returns "solders"

        assertEquals("solders", StaticTrojan.staticOpen())

        unmockkStatic(StaticTrojan::staticOpen)

        assertEquals("horse", StaticTrojan.staticOpen())
    }
}

API允许您轻松地模拟Kotlin对象,在上面的示例中,该对象仅用于使用@JvmStatic注释创建静态函数。

注意!这种方法使用从API级别 28 开始在Android P中可用的JVMTI 。您的应用程序可以使用较小的API编写,但您必须仅在Android P设备或更新的设备上运行测试。

于 2021-08-27T05:58:10.903 回答