android - 为什么我在创建内联 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 引用在测试之间总是不同的)。
在我开始努力重构项目中的所有测试之前,我想更好地了解性能提升,以确保将来不会出现任何问题。
解决方案
原来“性能提升”只是 android studio 对测试执行时间的误导。我使用了 JProfiler,发现内联方法调用和在 setup 方法中执行它都会导致调用Mockito.mock()
需要相同的时间来执行。唯一的区别是在堆栈跟踪中执行调用的位置,所以我假设 android studio 仅在某个点之后开始计数,这导致执行时间非常短。
我还使用 gradle 的内置分析器仔细检查并观察到相同的结果。无论模拟初始化方法如何,测试执行都需要相同的时间。
推荐阅读
- reactjs - useState 不读取 if 语句之外的变量
- r - 尝试在 R 中处理时间序列时出现“FUN 错误(newX[, i], ...):找不到对象'trend.ts'”
- google-apps-script - 在电子邮件中获取 Google 表单回复
- firebase - 如何使用 Firebase SDK 访问 Hacker News API?
- javascript - 当我在 Chrome 扩展程序中单击 popup.html 中的某个项目时,我无法将任何内容保存到 chrome 或页面的存储中
- python - 新的 Dockerfile 不能使用 .env 文件读取 Python 中的环境变量
- ruby-on-rails - Ruby on Rails 更改日期未保存到对象
- java - 使用 Java 8 流在不同集合中收集 [0..n]、[n+1..l] 元素的最佳方法是什么?
- c - C 程序在 Visual Studio 代码调试期间不会在断点处停止
- javascript - 反应:在特定组件上应用正文溢出