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

Add doReturn().on { method() } helper to KStubbing #481

Merged
merged 1 commit into from
Mar 17, 2023

Conversation

thecodewarrior
Copy link
Contributor

This implements my proposed solution to #453, which provides a cleaner way to use the doReturn().when(mock).methodCall() mocking syntax. Mockito-kotlin provides a .whenever(mock) extension, since when is a reserved keyword in Kotlin, however inside a KStubbing you still need to specify the instance, which gets messy and verbose.

I added one extension function to KStubbing: Stubber.on(methodCall).

// before
val myMock = mock<MyClass> {
    doReturn("first").whenever(it).myMethod()
}
// after
val myMock = mock<MyClass> {
    doReturn("first").on { myMethod() }
}

I went with doReturn(...).on { ... } instead of doReturn(...) on { ... } because of the difference in how the results are chained:

val myMock = mock<MyClass> {
    // `on {} doReturn X doThrow Y`   - uniformly uses spaces
    // `doReturn(X).doThrow(Y).on {}` - uniformly uses dots
    // `doReturn(X).doThrow(Y) on {}` - inconsitent dots/spaces

    on { myMethod() } doReturn "value" doThrow IllegalStateException()
    doReturn("first").doReturn("second").doThrow(IllegalStateException()).on { myMethod() }
    doReturn("first").doReturn("second").doThrow(IllegalStateException()) on { myMethod() }
}

This method doesn't provide type safety, but it's a simple and effective solution. We could create an entire custom KStubber<T> class that does type safety, however, while that will provide type safety, it won't provide type inference, since you do the .on { myMethod() } at the end.

We could provide type safety and type inference given a different syntax, but it's awkward.

val myMock = mock<MyClass> {
    on({ myMethod() }) {
        doReturn("first")
        doReturn("second")
        doThrow(IllegalStateException())
    }
}

There are probably other possible syntaxes, but this is the best one I came up with.

Copy link
Contributor

@TimvdLippe TimvdLippe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@TimvdLippe TimvdLippe merged commit 1ab7540 into mockito:main Mar 17, 2023
@thecodewarrior thecodewarrior deleted the stubber-on-extension branch March 17, 2023 21:36
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

Successfully merging this pull request may close these issues.

None yet

2 participants