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

Unable to mock wrapped function with value class param #667

Closed
3 tasks done
Rattenkrieg opened this issue Jul 12, 2021 · 3 comments
Closed
3 tasks done

Unable to mock wrapped function with value class param #667

Rattenkrieg opened this issue Jul 12, 2021 · 3 comments

Comments

@Rattenkrieg
Copy link

Consider following code

@JvmInline
value class DummyValue(val value: Int)

class DummyService {

    fun processValue(value: DummyValue): DummyValue {
        return value
    }

    fun callWrapped(value: DummyValue) = processValue(value)
}

fun main() {

    val mock = mockk<DummyService>()

    every { mock.processValue(DummyValue(1)) } returns DummyValue(42)

    println(mock.callWrapped(DummyValue(1)))

    verify { mock.processValue(DummyValue(1)) }
}

Prerequisites

Please answer the following questions for yourself before submitting an issue.

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed

Expected Behavior

DummyValue(42) printed

Current Behavior

Exception in thread "main" io.mockk.MockKException: no answer found for: DummyService(#1).callWrapped--ycYzh0(1)

  • MockK version: 1.12.0
  • OS: macOS BigSur 11.4
  • Kotlin version: 1.5.20
  • JDK version: Adopt OpenJDK 16.0.1
  • JUnit version: I'm running simple main method
  • Type of test: I'm running simple main method
@Rattenkrieg Rattenkrieg changed the title Unable to mock wrapped function Unable to mock wrapped function with value class param Jul 12, 2021
@d35h
Copy link

d35h commented Jul 19, 2021

I don't think that the mocking is the problem here, since you're using mockk, it tries to mock all the methods of DummyService, for the purpose of mocking only certain methods (in your case processValue only), you should be using spyk, i.e.:

    fun main() {
        val mock = spyk<DummyService>()
        every { mock.processValue(DummyValue(1)) } returns DummyValue(42)
        println(mock.callWrapped(DummyValue(1)))
        verify { mock.processValue(DummyValue(1)) }
    }

However, it won't work because of this https://youtrack.jetbrains.com/issue/KT-46477#focus=Comments-27-4952485.0-0

As a temporary workaround until Kotlin 1.5.30-M1 is released, you could make your return type nullable:

 fun processValue(value: DummyValue): DummyValue? = value

Or in case you really want to use mockk, you can make it call the original implementation by doing this:

    fun main() {
        val mock = mockk<DummyService>()
        every { mock.processValue(DummyValue(1)) } returns DummyValue(42)
        every { mock.callWrapped(DummyValue(1)) } answers { callOriginal() }
        println(mock.callWrapped(DummyValue(1)))
        verify { mock.processValue(DummyValue(1)) }
    }

@Rattenkrieg
Copy link
Author

Thanks @d35h actually my issue is more complicated one and I tried to come up with a simple demo that has an issue on it's own as you demonstrated. For now I've changed the test setup to avoid mocking problematic dependencies and I'll try the spyk approach as soon as 1.5.30 is shipped.

@stale
Copy link

stale bot commented Sep 21, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you are sure that this issue is important and should not be marked as stale just ask to put an important label.

@stale stale bot added the stale label Sep 21, 2021
@stale stale bot closed this as completed Oct 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants