Reputation: 568
My class has a method with default parameters whose values are derived from an injected parameter:
class Slack @Inject constructor(
private val brokerSettings: BrokerSettings
) {
fun alert(
message: String,
responsible: String = brokerSettings.slack?.responsible ?: "<!here>",
channels: List<String>? = brokerSettings.slack?.channels
) {
...
}
}
I can construct a mockk<Slack>
, but when my test tries to invoke alert(message)
on it, relying on the default parameters, I get a null pointer exception in alert$default
.
If I change brokerSettings.slack
above to brokerSettings?.slack
, then it works - but warns me that I don't need the extra ?
.
I tried mocking the brokerSettings
field's getter:
val slack = mockk<Slack>(relaxed = true)
{
// every { [email protected] } answers { BrokerSettings() }
// every { this getProperty "brokerSettings" } propertyType BrokerSettings::class answers { BrokerSettings() }
}
but [email protected]
fails to compile if the field is private and throws an NPE just like the original problem if it's public, and this getProperty
fails with a reflection error.
I'm bodging for now by setting the defaults to null
and using ?:
to conditionally compute the defaults inside the function, but I'd prefer not to do that.
Any ideas?
Upvotes: 0
Views: 5183
Reputation: 19451
This is an edit/complete rewrite of my first answer. I obviously did pay too little attention to the real problem.
What you need to do is:
BrokerSettings
instanceslack
getterSlack
instance passing in the mockSlack
instance with a spyalert
functionslack.alert
callIn Kotlin:
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()) }
}
}
Upvotes: 1