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

Wrong value when mocking kotlin.Result #867

Closed
3 tasks done
steven-carrell opened this issue Jul 27, 2022 · 11 comments
Closed
3 tasks done

Wrong value when mocking kotlin.Result #867

steven-carrell opened this issue Jul 27, 2022 · 11 comments

Comments

@steven-carrell
Copy link

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

Failure Information (for bugs)

In mockk 1.12.4 I was able to mock a kotlin.Response return value on a function and get the generic value from it.

1.12.5 seems to have broken this and regardless of the Response.success(x) value, success always folds to a boolean false.

Code below.

Context

  • MockK version: 1.12.5
  • OS: macOS 11.5.2
  • Kotlin version: 1.7.10
  • JDK version: 11
  • JUnit version: 4.13.2
  • Type of test: unit test

Minimal reproducible code (the gist of this issue)

// -----------------------[ GRADLE DEFINITIONS ] -----------------------
dependencies {
    testImplementation("org.hamcrest:hamcrest-library:2.2")
    testImplementation("junit:junit:4.13.2")
    testImplementation("io.mockk:mockk:1.12.5")
}
// -----------------------[ YOUR CODE STARTS HERE ] -----------------------
import io.mockk.every
import io.mockk.mockk
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test

class ResultTest {
    interface ToMock {
        fun returnsResult(): kotlin.Result<String>
    }

    @Test
    fun `result value`() {
        val value = Result.success("something")
        val toMock = mockk<ToMock> {
            every { returnsResult() } returns value
        }
        // Expected: <Success(something)>
        //      but: was <Success(false)>
        assertThat(toMock.returnsResult(), equalTo(value))
    }
}
// -----------------------[ YOUR CODE ENDS HERE ] -----------------------
@svenjacobs
Copy link

I'm facing the same issue. The following test works with 1.12.4 but not with 1.12.5:

interface Source {
    fun getData(): Result<Boolean>
}

interface View {
    fun showError()
    fun showData()
}

class TestSubject(
    private val source: Source,
    private val view: View,
) {

    fun execute() {
        val result = source.getData()

        when {
            result.isFailure -> view.showError()
            result.getOrThrow() -> view.showData()
        }
    }
}

class ValueClassTest : WordSpec({

    val source = mockk<Source>()
    val view = mockk<View>()
    val subject = TestSubject(source, view)

    beforeEach {
        clearMocks(
            source,
            view,
        )
    }

    "execute" should {

        "show data" {
            every { source.getData() } returns Result.success(true)

            subject.execute()

            verify {
                view.showData()
            }
        }

        "show error" {
            every { source.getData() } returns Result.failure(NullPointerException())

            subject.execute()

            verify {
                view.showError()
            }
        }
    }
})

@SimonMarquis

This comment was marked as duplicate.

@ikurek
Copy link

ikurek commented Jul 29, 2022

I'm facing the same issue with 1.12.5. Everything works fine in 1.12.4

@qoomon
Copy link
Contributor

qoomon commented Jul 30, 2022

Should be fixed by #872

@qoomon
Copy link
Contributor

qoomon commented Aug 23, 2022

It was fixed with recent version 1.12.6

@sschuberth
Copy link

It was fixed with recent version 1.12.6

Unfortunately, something apparently went wrong with publishing that release.

@steven-carrell
Copy link
Author

Looks good on 1.12.7

@pphilipp
Copy link

Seems like the issue comes back. I have the Result.failure(Exception()) which wrapped with Result.success(Result.failure(Exception())).

version io.mockk:mockk:1.13.2

@caeus
Copy link

caeus commented Jul 11, 2023

Why was this closed, if not fixed?

@sschuberth
Copy link

Why was this closed, if not fixed?

Read above, there seems to be a regression.

@JWvanV
Copy link

JWvanV commented Jul 27, 2023

I also encountered this issue recently in io.mockk:mockk:1.13.5:

abstract class StateHolder<S>(defaultState: S) {

    private val mutableState = MutableStateFlow(defaultState)
    val stateFlow = mutableState.asStateFlow()

    val currentState: S
        get() = mutableState.value
}
class LoadingStateHolder() : StateHolder<Result<LoadingState>>(Result.failure(Exception())) {}
@RelaxedMockK
private lateinit var stateHolder: LoadingStateHolder

every { stateHolder.currentState } returns Result.failure(Exception("No state"))

Error: Cannot invoke "kotlin.Result.unbox-impl()" because the return value of "LoadingStateHolder.getCurrentState()" is null

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

No branches or pull requests

9 participants