Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Alexis Riksman-TomTom
    @AlexisRiksman-TomTom
    Yeah, I got the logic behind it.
    The mock object records what happens, in the verify we capture some parameters and inspect them in more detail.
    The confusing part is that this test captures callback functions, so they can be called in the test. But this is not really elegant, I will rework the code.
    Thanks for enlightening me on this !
    Mattia Tommasone
    @Raibaz
    np :)
    Daniel Freudenberger
    @dfreudenberger
    Hey there. How do I verify a method on a mock was called with an argument of type x? Sth like. verify { foo.bar(MyClass::class) }?
    verify { foo.bar(withArg { it is MyClass }) } seems to work. Is this the way to go?
    Mattia Tommasone
    @Raibaz
    i think you can also use verify { foo.bar(ofType(MyClass::class)) }
    1 reply
    sadhasivam
    @sadhasivam

    friends, i have a webFlux coRouter endpoints which has a kotlin muLogging statement. i would like to coVerify logger.info is executed in my Mockk unit-test case. any help would be appreciated. `fun myRouter() = coRouter {
    val logger = KotlinLogging.logger {}

    "/events".nest {
        POST { req ->
            val event = req.awaitBody<Event>()
            logger.info { event }
            ok().bodyValueAndAwait("")
        }
    }

    }`

    Mattia Tommasone
    @Raibaz
    i think you can do
    val mockLogger = mockk<KLogger>()
    mockkObject(KotlinLogging) 
    every { KotlinLogging.logger(any()) } returns mockLogger
    and then you can run verifications on your mockLogger
    Hayi Nukman
    @ha-yi

    Hi All,
    I wanna ask about mocking android ViewModel.
    I have a view model which having a few live data on it…

    I tried to mock it by

    val vm = mockk<CalibrationViewModel>(relaxed = true)
    every { vm.getCalibrationId() } returns "mocked”

    on these getCalibrationId()

    fun getCalibrationId(): String? {
        return _calibrationId.value // <— private live data object
    }

    but then I get an error like this:

    Caused by: java.lang.IllegalAccessError: tried to access class androidx.lifecycle.LiveData$ObserverWrapper from class androidx.lifecycle.LiveData$Subclass0

    I thought that mockk will completely stub all the methods and properties without actually calling the real things….
    any suggestions on this?
    thanks in advance.

    Hayi Nukman
    @ha-yi

    Another questions,
    it seems to be hard to mock the viewModel with the issues above, so instead of mocking it, I tried to use the real object from the ViewModel.

                val mockCalibration = CalibrationCreated(….)
                fragment.viewModel = CalibrationViewModel(appContext).apply {
                    setPitchAngle(22.3f)
                    setRollAngle(33.3f)
                    setExistingCalibration(mockCalibration)
                }
    
                println(fragment.viewModel.getRollAngle()) // 33.3f
                println(fragment.viewModel.getPitchAngle()) // 22.3f
                println(fragment.viewModel.getExistingCalibration()) // null, should be not null

    but whenever I get these calibration from live data that hold its value, it always null…

    here is the code inside these ViewModel

    class CalibrationViewModel(application: Application) : AndroidViewModel(application) {
    …
        private val _existingCalibration = MutableLiveData<CalibrationCreated>()
    
    
        fun setExistingCalibration(value: CalibrationCreated) {
            _existingCalibration.postValue(value)
        }
    
        fun getExistingCalibration(): CalibrationCreated? {
            return _existingCalibration.value
        }
    …
    }

    any suggestion really appreciated.
    Thanks in advance...

    Raman Gupta
    @rocketraman
    Upgrading to mockk 1.10.6 from 1.9.3 in my Kotlin multiplatform project seems to break it... seems to be related:
    Unable to build Kotlin project configuration
    
    org.gradle.internal.resolve.ArtifactNotFoundException: Could not find mockk-1.10.6-samplessources.jar (io.mockk:mockk:1.10.6).
    1 reply
    Ah, changing the dep to mockk-common fixed it
    Niranjan
    @niranjandroid

    object Foo {
    doSomething() {
    thows Exception()
    }
    }

    mockkObject(Foo)
    every(Foo.doSomething()) answers {}

    Please help me understand why every { } calls real method

    Vaibhav Sharda
    @vaibhavumd
    session.doWork { connection -> Code I am trying to test )
    Hello Everyone, I am new to mockk and Kotlin. I am trying to test a particular function which opens a stateless session and does some work and I am not sure how to I reach inside dowork lambda
    I am able to able to mock Stateless session and I have tired to do every {mockSession.doWork(any)} just runs which does not even go inside the dowork { code}. Any idea how to do this?
    bbaldino
    @bbaldino
    It looks like you want to capture the lambda argument that your code is passing to session.doWork, is that right?
    What you're doing there is mocking the doWork method and having it do nothing
    Vaibhav Sharda
    @vaibhavumd
    Yes, I have some code inside the doWork {Code is here} but I am not able to pass through the dowork
    How should I do it then? I want to test functions which I am calling inside the doWork { here }
    bbaldino
    @bbaldino
    If you want the lambda that's passed to doWork to run, then you might not need to mock session.doWork at all. If you need to mock some code of session, but not doWork, then you could use a spy
    If you want to capture the code that's being passed to doWork and run it manually as part of your test, then you can capture the lambda with a slot and then run it manually in your test
    Vaibhav Sharda
    @vaibhavumd
    Any examples of slot? or any link which I can reference? Thanks
    bbaldino
    @bbaldino
    See "capturing" here: https://mockk.io/
    Vaibhav Sharda
    @vaibhavumd
    Awesome, Thanks a lot for quick help.
    Luiz Aguiar
    @laguiar

    hello folks :wave:
    given the function:

    fun <T : Any> myFunction(foo: Foo, bar: Bar, response: KClass<T>): MyResponse<T> { do magic }

    how can it be mocked to control the returned object?
    I tried something like:

    every { mockedClass.myFunction(any(), any(), ofType(SomeType::class) } returns SomeType()

    but it didn't work... and using the type directly, myFunction(any(), any(), SomeType::class) is never matched.

    Mattia Tommasone
    @Raibaz

    i think the problem is that ofType(SomeType::class) matches arguments of type SomeType, while the third parameter of your myFunction is of type KClass
    if you mock the behavior like

    every { every { mockedClass.myFunction(any(), any(), any() } returns SomeType()

    It should work

    Luiz Aguiar
    @laguiar
     every { mockedClass.myFunction(any(), any(), any() } returns SomeType()
    @Raibaz any() is not accepted in the third parameter, it doesn't compile.
    Mattia Tommasone
    @Raibaz
    i’m guessing that’s because myFunction has more than one overloaded version, so you need to specify the signature you’re actually trying to mock
    every { mockedClass.myFunction(any(), any(), any<KClass<*>>() } should do
    Luiz Aguiar
    @laguiar
    @Raibaz thanks... any<KClass<*>>() helped... although it's throwing MockKException: no answer found for MyClass(#1).myFunction(content of SomeType pojo here)
    any additional idea here? thanks
    Ronak Shah
    @trulyronak

    hey all — what's the best way to see if a function is being called with the right shape string? I have a function getRandomIdAndRunMethod and I want to verify that I'm calling method with the right shape random id

    example code:

    
    getRandomId() {
        do server side stuff and return the id that (depending on other service) will be of shape xxxx-xxxx
    } 
    
    method(id) {
        sends an email to someone based on id
    }
    
    getRandomIdAndRunMethod() {}

    I'm trying to run this in a verify block and getting the error: No other calls allowed in stdObjectAnswer than equals/hashCode/toString

    Mattia Tommasone
    @Raibaz
    are you running all that in a verify block? that doesn’t seem right to me
    what you should be doing, imho, is something like
    every { getRandomId() } returns “someValue”
    
    getRandomIdAndRunMethod()
    
    verify { method(“someValue”) }
    this way you’d be driving the behavior for getRandomId and checking that your getRandomIdAndRunMethod calls method with the expected value
    kayFpunkt
    @kayFpunkt

    Hey have a problem by using a foreach loop of an object which is extending a Map. I try to setup my mocking like this

    val tableMock = mockk<MyTable>(relaxed = true, name = "My table Mock")
    val tableEntryMock = mockk<MyEntry>(relaxed = true, name = "My entry Mock")
    every { tableMock[any()] } returns tableEntryMock

    But in my foreach, where I'm iteration over MyTable nothing happen because its size is 0, obviously. So I try:

    val tableMock = mockk<MyTable>(relaxed = true, name = "My table Mock")
    val tableEntryMock = mockk<MyEntry>(relaxed = true, name = "My entry Mock")
    val expectedMap = mutableMapOf<Int, MyEntry>(1 to tableEntryMock)
    every { tableMock.iterator() } answers expectedMap.iterator()

    But the precompiler has a problem with my 'answers' :
    None of the following functions can be called with the arguments supplied. answers(Answer<MutableIterator<MutableMap.MutableEntry<Int, MyTable>>>) defined in io.mockk.MockKStubScope answers(MockKAnswerScope<MutableIterator<MutableMap.MutableEntry<Int, MyTable>>, MutableIterator<MutableMap.MutableEntry<Int, MyTable>>>.(Call) → MutableIterator<MutableMap.MutableEntry<Int, MyTable>>) defined in io.mockk.MockKStubScope

    Mattia Tommasone
    @Raibaz

    answers takes a block, not a value
    you should be doing

    every { tableMock.iterator() } returns expectedMap.iterator()

    or

    every { tableMock.iterator() } answers { expectedMap.iterator() }
    kayFpunkt
    @kayFpunkt

    answers takes a block, not a value
    you should be doing

    every { tableMock.iterator() } returns expectedMap.iterator()

    or

    every { tableMock.iterator() } answers { expectedMap.iterator() }

    Thanks to @Raibaz this doesn't solves the problem fully, but brings me one step forward (was using 'answers' wrong). Problem is a different type of the Iterators.

    Anna J McDougall
    @AJMcDee
    Hi friendos...
    I'm trying to verify that a call was made. I'm using verify (exactly =1) and there's no problem when passing in a normal string as an argument, but it's saying was not called when I use a list of strings as an argument. I've tried every combination of eq and similar that I can think of, but it's still insisting that the function hasn't been called when it definitely has. I thought it could be a reference vs value thing, but the eq thing negates that as an option. Any ideas?
    Mattia Tommasone
    @Raibaz
    can you please paste the two verify blocks you’re using, the one with the normal string and the one with the list of strings?
    Anna J McDougall
    @AJMcDee
    image.png
    Sorry I'm working on a virtual machine so only have screenshots
    image.png
    My two mocked calls:
    Both are necessary to get the correct results back, and the results coming back are correct, so it must be being called but still comes back as was not called.
    Mattia Tommasone
    @Raibaz
    can you try verifying the second function with any() rather than buildingIdList.buildingIds?
    Anna J McDougall
    @AJMcDee
    OK
    That's failing too! Guess it's not a list problem, then.
    Mattia Tommasone
    @Raibaz
    yep
    Anna J McDougall
    @AJMcDee
    OK I tried commenting out the repositoryMock call and it still works. Thanks for your help, I'll look into it some more!
    Mattia Tommasone
    @Raibaz
    np :)