In my current project there is a class that will later on be implemented by many others. This class provides some generators for delegated properties.
abstract class BaseClass {
protected val delegated1 get() = new Delegated1Impl()
protected val delegated2 get() = new Delegated2Impl()
...
}
This base class can be used this way:
class Example : BaseClass() {
var field1 by delegated1
var field2 by delegated2
}
Now I want to test these delegated generators. Some of them contain logic which I want to test, but for now I only want to know that everytime they are called they return a new instance.
Now my question is: how can I test these generators?
The generators are not visible outside of extending classes so I cannot simply create an instance of it and call these methods.
@Test
fun `delegated1 should always return a new instance`() {
val target = object: BaseClass()
val first = target.delegated1 // This does not work since it is protected
val second = target.delegated1
assertTrue(first !== second)
}
You need a new object created whenever you "call" the get
method. So how to test it? With a provider
A Provider<T>
is just an object that provides you new instances of a concrete class. Its signature is something like this:
interface Provider<T> {
fun get() : T
}
So you need to inject a new Provider<T>
into your BaseClass
:
abstract class BaseClass(
private val implementation1Provider : Provider<YourInterface>,
private val implementation2Provider : Provider<YourInterface>) {
protected val delegated1 get() = implementation1Provider.get()
protected val delegated2 get() = implementation2Provider.get()
...
}
Now you can inject your custom providers in the test and assert that they have been called:
@Test
fun `delegated1 should always return a new instance`() {
val implementation1Provider = ...
val target = Example(implementation1Provider, ...)
val first = target.field1
// assert that implementation1Provider.get() has been called
}