Asbertequals无法实现错误,但成功通过

发布于 2025-02-08 09:19:30 字数 1205 浏览 1 评论 0原文

我会有这些密封的接口

sealed interface Result<out T> {
    data class Success<T>(val data: T) : Result<T>
    data class Error(val exception: Throwable? = null) : Result<Nothing>
}

当我尝试assertequals成功的界面时, 。但是,当涉及到错误时,即使内容相同,它也会失败。这是一个简单的示例:

@Test
fun testSucess() = runTest {
    whenever(repository.login("email", "password"))
        .thenReturn(someValue)

    val expected = Result.Success(data = someValue)
    val actual = loginUseCase(LoginRequest("email", "password"))

    verify(repository).login("email", "password")
    assertEquals(expected, actual) // this will pass
}

@Test
fun testError() = runTest {
    val exception = RuntimeException("HTTP Error")
    whenever(repository.login("", ""))
        .thenThrow(exception)

    val expected = Result.Error(exception = exception)
    val actual = loginUseCase(LoginRequest("", ""))

    verify(repository).login("", "")
    assertEquals(expected, actual) // this will fail
    assertEquals(expected.toString(), actual.toString()) // this will pass
}

什么是导致此事的,什么可能解决的方法?我已经阅读了一些需要equals()的信息,但是我仍然感到困惑为什么仅在错误情况下发生,以及如何正确覆盖等于等于方法。

I have these sealed interface

sealed interface Result<out T> {
    data class Success<T>(val data: T) : Result<T>
    data class Error(val exception: Throwable? = null) : Result<Nothing>
}

when i tried to assertEquals the Success one, it pass. But when it comes to Error one, it will fail even though the content is identical. Here is simple example:

@Test
fun testSucess() = runTest {
    whenever(repository.login("email", "password"))
        .thenReturn(someValue)

    val expected = Result.Success(data = someValue)
    val actual = loginUseCase(LoginRequest("email", "password"))

    verify(repository).login("email", "password")
    assertEquals(expected, actual) // this will pass
}

@Test
fun testError() = runTest {
    val exception = RuntimeException("HTTP Error")
    whenever(repository.login("", ""))
        .thenThrow(exception)

    val expected = Result.Error(exception = exception)
    val actual = loginUseCase(LoginRequest("", ""))

    verify(repository).login("", "")
    assertEquals(expected, actual) // this will fail
    assertEquals(expected.toString(), actual.toString()) // this will pass
}

What is causing this and what is possible solution to this? I have read some info that it needs equals() to be overriden, but i still confused as to why it only happens in Error case only and how to properly override the equals method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拥抱影子 2025-02-15 09:19:30

kotlin中的数据类具有隐式生成的equals源自其所有属性。

您面临的问题可能是由于您的someValue的类型具有适当的equals函数,因此Equals适用于您的Success及其属性value。但是投掷没有等于函数,这意味着两个可投掷 s仅在它们是同一实例的情况下等于预期实际的情况。我只能猜测,在loginusecase中,该异常被包裹在另一个异常中,还是基于存储库抛出的一个创建一个新的异常?

kotlin已经有一个内置 result>结果 ,我强烈建议使用它而不是定义自己的。

尽管如此,如果您使用内置类型,则可能会遇到相同的问题,因为equals检查对于不同的异常实例仍然失败。

有几种方法可以解决:

  1. 定义您自己的异常类型,并覆盖等于函数,如果它们都是相同类型并且具有相同的消息,则返回true。
  2. 检查预期的是错误(或使用默认的结果键入enduce> enduce> endure> firese.firess.isfure),然后检查消息是否相同。
  3. 确保loginusecase抛出与存储库所抛出的异常实例完全相同。

Data classes in Kotlin have an implicitly generated equals function automatically derived from all their properties.

The problem you are facing is probably due to the fact that the type of your someValue has a proper equals function, so the equals works for your Success and its property value. But Throwable does not have an equals function which means that two Throwables are only equal if they are the same instance, which is obviously not the case for expected and actual in your test assertion. I can only guess that in loginUseCase, the exception is wrapped inside another exception, or a new exception is created based on the one thrown by the repository?

Kotlin already has a built-in Result type, and I strongly recommend using that one instead of defining your own.

Nonetheless, if you use the built-in type, you will probably face the same problem, since the equals check still fails for the different exception instances.

There are several ways to solve that:

  1. Define your own exception type and override the equals function to return true if they are both of the same type and have the same message.
  2. Check for expected is Error (or with the default Result type that expected.isFailure), and then check that the messages are the same.
  3. Make sure that loginUseCase throws exactly the same exception instance as is thrown by the repository.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文