模拟每个 {}.throws() 异常,测试失败

yno*_*tu. 13 kotlin mockk

当先前的方法调用抛出异常时,我需要验证是否未进行某个调用。

    // GIVEN
    every { relaxedMock.eats() }.throws(NotHungryException())
    
    // WHEN
    sut.live()
    
    // THEN
    verify (exactly = 0) { relaxedMock2.sleeps() }
Run Code Online (Sandbox Code Playgroud)

这段代码有问题,它失败是因为抛出异常,而不是因为验证失败。

小智 19

我知道你的WHEN块总是会抛出异常。在这种情况下,从我的角度来看,你有多种选择:

  1. 简单的 Kotlin。用 try-catch 块包裹WHEN块,例如:
// GIVEN
every { relaxedMock.eats() }.throws(NotHungryException())
    
// WHEN
var exceptionThrown: Boolean = false
try {
    sut.live()
} catch(exception: NotHungryException) {
    // Maybe put some assertions on the exception here.
    exceptionThrown = true
}
assertTrue(exceptionThrown)
    
// THEN
verify (exactly = 0) { relaxedMock2.sleeps() }
Run Code Online (Sandbox Code Playgroud)
  1. 对于更好的代码,您可以使用JUnit5 API 的 AssertionsassertThrows将期望特定代码段抛出异常。如果没有抛出异常,它将导致测试失败。它还会返回抛出的异常,供您检查。
import org.junit.jupiter.api.Assertions

// GIVEN
every { relaxedMock.eats() }.throws(NotHungryException())
    
// WHEN
val exception = Assertions.assertThrows(NotHungryException::class.java) { sut.live() }
    
// THEN
verify (exactly = 0) { relaxedMock2.sleeps() }
Run Code Online (Sandbox Code Playgroud)
  1. 如果您使用Kotest,则可以使用shouldThrow断言。它还允许您检索抛出的异常并验证其类型。
import io.kotest.assertions.throwables.shouldThrow

// GIVEN
every { relaxedMock.eats() }.throws(NotHungryException())
    
// WHEN
val exception = shouldThrow<NotHungryException> { sut.live() }
    
// THEN
verify (exactly = 0) { relaxedMock2.sleeps() }
Run Code Online (Sandbox Code Playgroud)