Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Mocking varargs #52

Closed
UlfHesselbarth opened this issue Mar 23, 2018 · 10 comments
Closed

Bug: Mocking varargs #52

UlfHesselbarth opened this issue Mar 23, 2018 · 10 comments
Labels

Comments

@UlfHesselbarth
Copy link

UlfHesselbarth commented Mar 23, 2018

In Mockito there is anyVararg() but mockk does not have this.
Consider the following example:

interface Foo {
   fun foo(vararg args: String, otherArg: String)
   fun foo(args: List<String>, otherArg: String)
}

@Test
fun varargTest() {
   val mock = mockk<Foo>()
   // this works as expected, matching the List<String> version
   every { mock.foo(args = any<List<String>>(), otherArg = any()) } just Runs

   // this does not work, compiles but fails at runtime with:
   // io.mockk.MockKException: Failed matching mocking signature for
   // Foo(#1).foo([529c407ddf5619f7], -4522a650db14c274)
   // left matchers: [any()]
   every { mock.foo(args = *arrayOf(any()), otherArg = any()) } just Runs
}

Is there another way to mock the vararg version of foo?

@oleksiyp
Copy link
Collaborator

Look like issue is appearing when using interface or abstract class. When using simple class it is passing:

    class Foo {
        fun foo(vararg args: String, otherArg: String) {

        }
        fun foo(args: List<String>, otherArg: String) {
            
        }
    }

I've checked underlying reflection call and seems Kotlin is just not returning correct value. So it is a Kotlin reflection API bug

@oleksiyp oleksiyp added Kotlin bug bug in Kotlin language bug and removed Kotlin bug bug in Kotlin language labels Mar 25, 2018
@oleksiyp
Copy link
Collaborator

After additional checking, it appears that pure interface is working. So it is related to metadata propagation i.e. while using interface MockK needs to create a proxy subclass and Kotlin metadata is not copied to that subclass.

@oleksiyp
Copy link
Collaborator

oleksiyp commented Mar 25, 2018

So yes this because of subclassing. issue52 branch fixes it but makes builds 25% slower. This is something to solve additionally.

@gildor
Copy link

gildor commented May 2, 2018

@oleksiyp I cannot verify vararg, method with vararg always fail verification (except verify(exactly = 0), just because of it never called)
Can you confirm, that this is related to this issue or I do something wrong?

@oleksiyp
Copy link
Collaborator

oleksiyp commented May 2, 2018

Very probable that this is related.
Fix/workaround is making MockK slow, so it was not merged.
Some caching to be applied.
Or maybe other ways to fix it.

Right now(one/two weeks) I'm quite free for doing MockK improvements/fixes but focused on Android instrumentation test which is a big feature. Will get back to such not very big things after releasing it.

I desperately need good co-author :-)

@oleksiyp
Copy link
Collaborator

In version 1.8 it should be fixed. Please check

@oleksiyp oleksiyp changed the title Mocking varargs Bug: Mocking varargs May 16, 2018
@oleksiyp
Copy link
Collaborator

Seems it was fixed, reopen if it is not

@darrenhaken
Copy link

What's the fix for this @oleksiyp ? I'm using 1.9 and having trouble mocking a varargs.

@oleksiyp
Copy link
Collaborator

In version 1.8 it should be fixed. Please check

Please report as a new bug

@darrenhaken
Copy link

@oleksiyp new issue opened at #224

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants