If I have a (simplified) class that looks like this:
class MyManager @JvmOverloads constructor(/*constructor args*/) : MyManagerInterface {
@Inject
lateinit var myLogger: MyLogger
init {
component = DaggerLoggerComponent.builder()
.loggerModule(LoggerModule(internalLogger))
.build()
component.inject(this)
}
companion object {
lateinit var component: RemoteLoggerComponent
private set
}
}
When unit testing, how on earth do I mock the component in the companion object?
I've tried all kinds of tricks using Mockito, MockK etc but I come up against several obstacles.
The CUT (class-under-test) is another class that is using the MyManager component to inject its dependencies in its init block like so:
init {
if(applicationContext == null) {
throw IllegalStateException("Application Context must not be null")
} else {
MyManager.component.inject(this)
}
}
Basically, I'd be happy if the injection does nothing because I can set the dependencies externally for the sake of testing.
All help appreciated. Including if you think I'm coding this wrong. I'm relatively new to Kotlin and Dagger. Thanks.
However, in Kotlin, you can also call callMe() method by using the class name, i.e, Person in this case. For that, you need to create a companion object by marking object declaration with companion keyword.
To create a companion object, you need to add the companion keyword in front of the object declaration. The output of the above code is “ You are calling me :) ” This is all about the companion object in Kotlin. Hope you liked the blog and will use the concept of companion in your Android application.
Mocking for unit testing is when you create an object that implements the behavior of a real subsystem in controlled ways. In short, mocks are used as a replacement for a dependency.
There are times we need to use a companion object to define class members that are going to be used independently of any instance of that class. The Kotlin compiler guarantees we will have one and only one instance of a companion object.
Basically, using MockK, you need code like that:
mockkObject(MyManager)
every { MyManager.component.someOp(...) } returns 5
Not sure I understand all the details about the injection. As you said you can disable it.
Do not forget to unmock companion objects. Otherwise, mocked version shall be used after the current test.
Blocked mocking shall unmock automatically for us:
mockkObject(MyManager) {
every { MyManager.component.someOp(...) } returns 5
act()
verify {
...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With