首页 > 解决方案 > 为什么我在创建内联 mockito 模拟时会看到性能提升?

问题描述

使用 mockito 2 时,我发现在内联实例化 mock 与使用 @Mock 注释或在 setup 方法中实例化它们时,性能有了巨大的提升。这让我非常困惑,因为文档中没有任何地方不鼓励内联实例化模拟,尽管性能明显提升。所有时间均取自显示执行时间的 Android Studio 的测试运行器输出。

我用一个非常简单的测试创建了一个新项目:

    private val mockBanana: Banana

    private lateinit var cut: Person

    @Before
    fun setup(){
        cut = Person()
    }

    @Test
    fun check(){
        cut.banana = mockBanana

        cut.eat()

        verify(mockBanana).grow()
        verify(mockBanana).harvest()
        verify(mockBanana).peelOff()
        verify(mockBanana).eat()

    }

然后,我只是更改了创建模拟的方式。

慢方法:在 setup 中调用 mock。耗时 400 毫秒

    @Before
    fun setup(){
        mockBanana = mock(Banana::class.java)
        cut = Person()
    }

慢方法:mock注解。耗时 430 毫秒

    @Mock
    private lateinit var mockBanana: Banana

快速方法:调用模拟内联。需要 25 毫秒

    private val mockBanana: Banana = mock(Banana::class.java)

最初我认为性能提升是由于每个类只创建一次模拟,然后在所有测试之间共享,这将是一个交易破坏者。然而,进一步的测试毫无疑问地表明这不是原因(我在 mockito 代码中使用了断点和日志,并且多次创建了 mock。此外,mock 引用在测试之间总是不同的)。

在我开始努力重构项目中的所有测试之前,我想更好地了解性能提升,以确保将来不会出现任何问题。

标签: androidperformanceunit-testingjunitmockito

解决方案


原来“性能提升”只是 android studio 对测试执行时间的误导。我使用了 JProfiler,发现内联方法调用和在 setup 方法中执行它都会导致调用Mockito.mock()需要相同的时间来执行。唯一的区别是在堆栈跟踪中执行调用的位置,所以我假设 android studio 仅在某个点之后开始计数,这导致执行时间非常短。

我还使用 gradle 的内置分析器仔细检查并观察到相同的结果。无论模拟初始化方法如何,测试执行都需要相同的时间。


推荐阅读