Closed Nimrodda closed 5 years ago
Mockito.doNothing()
and its related Stubber
functions are provided as a workaround for "rare occasions when you cannot use Mockito.when(Object)
". One example is stubbing methods that return Void
: the Java compiler doesn't allow Void
inside brackets.
In this case, you're not returning Void
, you're returning Unit
, and you're better off returning to the non-workaround solutions: whenever(mock.foo()).thenThrow(RuntimeException::class.java)
is allowed.
Full example:
class StubSuspendUnitTest {
@Test
fun `stubbing on suspending unit`() = runBlocking {
val testSubject: SomeInterface = mock()
whenever(testSubject.suspendingUnit())
.thenReturn(Unit)
.thenThrow(RuntimeException("Foo"))
expect(testSubject.suspendingUnit()).toBe(Unit)
expectErrorWithMessage("Foo") on { runBlocking { testSubject.suspendingUnit() } }
}
}
interface SomeInterface {
suspend fun suspendingUnit(): Unit
}
Oh yeah, I can't believe I missed that. Unit after all is just an object... Thanks a lot! :)
i did something like this
when(foo.save("key", "value")).thenReturn(Unit)
@nhaarman In my case, when a suspend function of a mocked or spied object is called, I don't want it to do whatever it has inside. So its like doNothing but that now for functions that return a Unit. But now it does not work as specified above. Any workaround for this?
@iadcialim could you please share you gist?
@radityagumay I believe this is the problem that @iadcialim is facing:
class StubSuspendingTest {
@Test
fun `stubbing on suspending unit`() = runBlocking {
val testSubject: SomeClass = spy(SomeClass()) // NOTE: spy vs mock
whenever(testSubject.suspendingUnit()) // this calls the actual method impl
.thenReturn(Unit)
.thenThrow(RuntimeException("Foo"))
assertEquals(Unit, testSubject.suspendingUnit())
try {
testSubject.suspendingUnit()
} catch (error: Throwable) {
assertEquals("Foo", error.message)
}
}
}
interface SomeInterface {
suspend fun suspendingUnit(): Unit
}
class SomeClass : SomeInterface {
override suspend fun suspendingUnit() {
TODO("not implemented")
}
}
@iadcialim You can use
doReturn(Unit).whenever(spy).functionReturningUnit()
which does not execute functionReturningUnit()
as
whenever(spy.functionReturningUnit()).thenReturn(Unit)
would.
Mocking Unit method where the first call should
doNothing()
and then 2nddoThrow()
, produces the following error:Only void methods can doNothing()!
Example:
doNothing().doThrow(RuntimeException::class.java).whenever(mock).foo()
wherefoo()
issuspend fun foo()
.