Klitos Kyriacou
01/24/2024, 3:27 PMclass ClassBeingMocked(val arg: String) {
fun foo(n: Int = arg.length) {
println("foo($n) called")
}
}
class ClassBeingTested(val a: ClassBeingMocked) {
fun bar() {
a.foo()
}
}
class MyJunitTest {
val a = mockk<ClassBeingMocked>(relaxed = true)
val b = ClassBeingTested(a)
@Test
fun test1() {
b.bar()
}
}
Notice that ClassBeingMocked.foo
takes a default parameter that depends on a property given as constructor parameter. The mock instance doesn't use this constructor parameter, as it's a mock. ClassBeingTested
relies on the default value of this function.
The above test throws NullPointerException: Cannot invoke "String.length()" because "<parameter1>.arg" is null
. The stack trace starts at the line where foo
is implemented, in class ClassBeingMocked
.
If a
is a mock instance, why does the stack trace show that it's going to the real class? Furthermore, can I somehow fix this without changing ClassBeingTested
to pass an actual parameter instead of the default?Mattia Tommasone
01/24/2024, 3:40 PMarg
in the constructor as well?
otherwise, can you please try explicitly mocking the foo
function, i.e. making the mock for ClassBeingMocked
not relaxed?Klitos Kyriacou
01/24/2024, 4:13 PMClassBeingMocked
is not a String (I just used String for simplicity) but a complex dependency that's difficult to choose a default for.
Also, trying val a = mockk<ClassBeingMocked> { every foo(any()) just runs }
gives the same problem.thanksforallthefish
01/24/2024, 5:11 PMclass ClassBeingMocked(val arg: String) {
val foo: Int
get() = arg.length
fun foo(n: Int = foo) {
println("foo($n) called")
}
}
class MyJunitTest {
val a = mockk<ClassBeingMocked>(relaxed = true)
val b = ClassBeingTested(a)
@Test
fun test1() {
every { a.foo } returns 2
b.bar()
}
}
that works. It would be interesting to see a more real example, it smells like a design issue
also just forfeiting the default parameter might be an option, then you don't even have to change your test
class ClassBeingMocked(val arg: String) {
fun foo() = foo(arg.length)
fun foo(n: Int) {
println("foo($n) called")
}
}
Klitos Kyriacou
01/24/2024, 5:21 PM