Yeah, looks inconvenient. Is the method how to properly test protected methods in final classes already found ?
You could use opt-in annotations and simply do a module-wide opt-in for the test module only.
E.g.:
@RequiresOptIn("This method is `internal` only for unit tests")
annotation class VisibleForUnitTests
class Foo {
@VisibleForUnitTests
internal fun bar() = TODO()
}
// Add compiler option "-opt-in=org.mylibrary.VisibleForUnitTests" in gradle config for the test module
// Then in tests
class FooUnitTests {
@Test fun barTest() {
Foo().bar() // Doesn't even need a `@OptIn(VisibleForUnitTests::class)` because of the compiler argument
}
}
@franco why do you make yourself so complicated? one way to do is you can create a function that will return your protected abstract function then you can set that to @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE | NONE)
@kyay10 so you are actually creating your own @VisibleForTesting
(which is only usable for Android if I get it right?) - nice idea!
But that wouldnât work for protected functions, only for private ones, unless I am missing something?
Well the point is that you change your protected and private functions to be internal
and annotated with VisibleForTesting
, which forces you everywhere else to not use those functions because youâll read the opt-in message and realise that you shouldnât opt-in to using those methods. Then in your gradle config you make the test sourceset automatically opt in to VisibleForTesting
through the compiler option I mentioned, and hence your test code will automatically be able to access all VisibleForTesting
methods without opting in manually.
@kyay10 > you change your protected and private functions to be internal
Well, as I said before, this of course works for private methods but NOT for protected.
But when you change protected
to internal
, you actually lose visibility which is not an option. protected
method are meant to be used from outside, even outside your module.
So⊠still no solution
I havenât done it myself but I assume https://mockk.io/ would work. Youâd make a spy on your class, possibly abstract or an interface, do some verify declarations and It would magically (*bytecode manipulation) work like all things in Mockkâitâs quite a library.
Mockk supports mocks and spies with private methods as well.