Как вы издеваетесь над равенством? - PullRequest
0 голосов
/ 05 февраля 2019

Допустим, у меня есть интерфейс

interface IFoo{
    val foo:String
}

, и я хочу создать классы, равные IFF их foo совпадениям строк.

Простой пример:

class A(override val foo:String):IFoo{
    val somethingIrrelevant = "bar"

    override fun equals(other: Any?): Boolean {
        return if(other is IFoo) foo == other.foo else false
    }

    override fun hashCode(): Int {
        return Objects.hash(foo)
    }
}

Кажется относительно простым, но этот тестовый пример:

@Test
fun mockingEquality(){
    //given
    val a = A("alpha")
    val b = A("alpha")

    assertThat(a,`is`(b)) //succeeds


    //when
    val c = mock(A::class.java)
    whenever(c.foo).thenReturn("alpha")

    //then
    assertThat(c, `is`(a)) //fails
}

не удается с

Expected: is <A@589b17d>
     but: was <Mock for A, hashCode: 263885523>

Почему это так?И как правильно смоделировать класс A для успешного выполнения этого теста?

1 Ответ

0 голосов
/ 05 февраля 2019

Проблема здесь в том, что когда вы создаете макет, этот объект не имеет поведения, если вы явно не имитируете его.Это включает в себя ваши equals и hashCode методы.

В вашем примере, одним из "исправлений" было бы использование методов equals и hashCode, но, очевидно, это не добавляет никакой ценности вашему тесту.Тривиально, вы можете инвертировать ваше утверждение (assertThat(a, is(c))), которое работает, потому что конечный результат будет a.equals(c), а a является реальным экземпляром класса A вместо макета и имеет свойство .foomock.

Я подозреваю, что ваши примеры просто чрезмерно упрощены, но в этих конкретных случаях вы предпочитаете просто создавать реальный экземпляр вместо насмешки (например, val c = A("alpha"), а не mock(A::class.java)).

Некоторые другие подходы здесь могут быть:

Другой подход заключается в использовании шпиона, если вы можете получить реальный экземпляр класса.Например:

val c = spy(A("other value"))
doReturn("mock value").whenever(c).foo 

Но в документации вы можете видеть, что эти способы частичной насмешки над классом не рекомендуются.

...