https://kotlinlang.org logo
#mockk
Title
# mockk
x

xenomachina

09/19/2023, 11:43 PM
I have an abstract class that I want to mock, and I want the mocks to pass through to the real implementation if there is one, but throw an exception if a method/property that is not implemented is called. Is this possible without having to
every { implementedMethod() } answers { callOriginal() }
for every single implemented method/property?
k

Klitos Kyriacou

09/20/2023, 8:19 AM
Wouldn't it be easier to extend the abstract class with a concrete class that throws exceptions instead of using Mockk?
1
x

xenomachina

09/20/2023, 4:35 PM
Yes, I can do that, but there are almost 30 properties that I'd need to override. They're abstract because in "real" code we want to ensure they have real implementations, but in tests we'd just like them to fail at runtime.
k

Klitos Kyriacou

09/20/2023, 5:00 PM
If your class has 30 abstract properties, it sounds likely that it's violating the Single Responsibility Principle. Nevertheless, you can use
spyk
which can spy on abstract classes. It's not exactly what you want as it makes abstract methods have default behaviour instead of throwing an exception. That default behaviour is to do nothing for functions returning Unit, return 0 for integral return values, and null for objects (even for return types that are non-nullable!)
x

xenomachina

09/20/2023, 5:22 PM
Yes, there's definitely some cleanup required in this code, but one step at a time. 😄 For what it's worth, the thing in question is representing the full set of configuration parameters to a service. Is there a way to change the behavior of
spyk
for abstract methods?
I tried modifying the Reflection matchers example from mockk's README, like this:
Copy code
fun mockConfig() : Config {
        val props = AbstractTestConfig::class.memberProperties
        return mockk<AbstractTestConfig> {
            props.forEach { prop ->
                every { prop.get(this@mockk) } answers { callOriginal() }
            }
        }
    }
but this seems to have the same problem: abstract properties return 0 or null. It also strangely did not seem to "see" the overrides in
AbstractTestConfig
. It treated those properties the same way it treated abstract properties.
3 Views