kotlin - 当方法的默认参数需要注入字段时如何模拟?
问题描述
我的类有一个带有默认参数的方法,其值是从注入的参数派生的:
class Slack @Inject constructor(
private val brokerSettings: BrokerSettings
) {
fun alert(
message: String,
responsible: String = brokerSettings.slack?.responsible ?: "<!here>",
channels: List<String>? = brokerSettings.slack?.channels
) {
...
}
}
我可以构造一个mockk<Slack>
,但是当我的测试尝试调用alert(message)
它时,依赖于默认参数,我在alert$default
.
如果我将brokerSettings.slack
上面更改为brokerSettings?.slack
,那么它可以工作 - 但警告我我不需要额外的?
.
我试着嘲笑这个brokerSettings
领域的吸气剂:
val slack = mockk<Slack>(relaxed = true)
{
// every { this@mockk.brokerSettings } answers { BrokerSettings() }
// every { this getProperty "brokerSettings" } propertyType BrokerSettings::class answers { BrokerSettings() }
}
但this@mockk.brokerSettings
如果该字段是私有的,则无法编译,并且如果它是公共的,则会像原始问题一样抛出 NPE,并且会this getProperty
因反射错误而失败。
我现在通过将默认值设置为null
并使用?:
来有条件地计算函数内部的默认值,但我不想这样做。
有任何想法吗?
解决方案
这是我的第一个答案的编辑/完整重写。我显然对真正的问题关注得太少了。
你需要做的是:
BrokerSettings
为实例创建一个模拟- 将模拟配置为不会在
slack
getter上失败 - 创建一个传入模拟的真实
Slack
实例 Slack
用间谍包装该实例- 将该间谍配置为不在
alert
函数中执行任何实际操作 - 把间谍放到你的班级接受测试
- 调用你要测试的方法
- 验证
slack.alert
通话
在科特林:
class SlackUsingClass(private val slack: Slack) {
fun doIt(message: String) {
slack.alert(message)
}
}
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import org.junit.jupiter.api.Test
class SlackUsingClassTest {
@Test
fun `should call slack`() {
val brokerSettings = mockk<BrokerSettings>()
every { brokerSettings.slack } returns null
val slack = spyk(Slack(brokerSettings))
every { slack.alert(any(), any(), any())} just Runs
val slackUsingClass = SlackUsingClass(slack)
slackUsingClass.doIt("test")
verify { slack.alert("test", any(), any()) }
}
}
推荐阅读
- php - Laravel sanctum 寻找 api_token 列
- ios - UITextField 在 iOS 14 中抛出各种错误
- javascript - 禁用所有按钮并在定义秒后重新启用 Javascript
- python - Python:如何仅将完整的单词“i”大写?
- node.js - TypeError:在 Vuex 4 和 Vue 3 上服务时无法读取未定义的属性“getters”
- python-3.x - 使用类属性作为参数使用 f 字符串进行浮点格式化
- maven - 我自己的仓库的 POM 丢失,没有可用的依赖信息
- node.js - ReferenceError:即使我已经导入了 parseCookies,也没有定义它
- mysql - 在 MySQL 中使用 UNION ALL 的子查询
- mysql - PHPMYADMIN 登录表单隐藏