android - 自定义 JUnit 规则允许所有测试无论如何都通过

标签 android junit kotlin mockito powermock

我有一个文件引用了一些静态方法:

class MyViewModel {

    fun test() { }

    companion object {
        private val MY_STRING = ResourceGrabber.grabString(R.string.blah_blah)
    }
}

在我对此文件的 JUnit 测试中,我编写了一些代码来模拟设置中的资源采集器。这编译并运行,下面的测试失败了,正如我所期望的那样:

@PrepareForTest(ResourceGrabber::class)
@RunWith(PowerMockRunner::class)
class MyViewModelTest {
    private lateinit var viewModel: MyViewModel

    @Before
    fun setup() {
        PowerMockito.mockStatic(ResourceGrabber::class.java)
        val mockResourceGrabber = Mockito.mock(ResourceGrabber::class.java)

        whenever(mockResourceGrabber.grabString(Mockito.anyInt())).thenAnswer { invocation ->
            val res: Int? = invocation?.arguments?.get(0) as? Int
            TestResourceGrabber.grabString(res)
        }

        viewModel = MyViewModel()
    }

    @Test
    fun someTest() {
        // Fails, as expected.
        assertEquals(2, 3)
    }
}

这里是事情变得奇怪的地方。我最近了解了自定义 JUnit 规则,您可以使用这些规则来避免测试中出现一些重复代码。在这种情况下,我不想将我的资源采集器工作复制并粘贴到使用它的每个测试套件中,所以我制定了一个自定义规则:

class ResourceGrabberRule : TestRule {
    override fun apply(base: Statement?, description: Description?): Statement {
        return object : Statement() {
            override fun evaluate() {
                PowerMockito.mockStatic(ResourceGrabber::class.java)
                val mockResourceGrabber = Mockito.mock(ResourceGrabber::class.java)

                whenever(mockResourceGrabber.grabString(Mockito.anyInt())).thenAnswer { invocation ->
                    val res: Int? = invocation?.arguments?.get(0) as? Int
                    TestResourceGrabber.grabString(res)
                }
            }
        }
    }
}

下面是它的实现。疯狂的是,现在无论如何,每个测试都通过了:

@PrepareForTest(ResourceGrabber::class)
@RunWith(PowerMockRunner::class)
class MyViewModelTest {
    private lateinit var viewModel: MyViewModel

    @Rule
    @JvmField
    val resourceGrabber = ResourceGrabberRule()

    @Before
    fun setup() {
        viewModel = MyViewModel()
    }

    @Test
    fun someTest() {
        // PASSES!!!?!?!?!?!
        assertEquals(2, 3)
    }
}

我不确定问题出在哪里。我试过从 Android Studio 和命令行构建和运行测试。我不知道是我的规则实现不正确,还是与 Powermock 连接的 JUnit 规则有问题,还是 Kotlin 注释处理有问题。测试会编译并运行,但无论测试本身内部有什么,都会通过。

我愿意接受关于这里架构的评论(我相信社区有很多),但我真的在寻找一个解释,解释为什么我写的规则通过了每一个测试。

最佳答案

在您的自定义 TestRule 中,您需要调用 base.evaluate() 来继续规则链 https://github.com/junit-team/junit4/wiki/rules#custom-rules

关于android - 自定义 JUnit 规则允许所有测试无论如何都通过,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52284207/

相关文章:

android - 在半屏上开始另一个 Activity (按 Intent )

android - 在 Listview onItemClick() 监听器不工作?

android - 如何在 Android 中通过主题设置任何小部件的宽度/高度

java - 从包含内容的字符串中删除 HTML 标签

java - 我的 Android 应用程序崩溃,触摸按钮无法正常工作

python-2.7 - Behave (BDD) 是否适用于 Python 3.4?

java - Micronaut 与 MockitoTests

java - 使用 Avro Schema 注册表的 Kafka 消费者单元测试失败

io - 如何在Kotlin中获取不带扩展名的文件名

android - Kotlin 全局变量显示为零 "0"