Как использовать Mockito Argument Capture для проверки значения свойства в объекте, переданном издеваемому методу? [Дубликат]

14
задан Tom Tucker 1 February 2012 в 06:52
поделиться

4 ответа

Используйте Answer, чтобы проверить значение аргумента при вызове метода. Вы можете либо выбросить AssertionError в Answer, если значение неверно, либо вы можете сохранить значение, и выполнить свое утверждение в конце.

11
ответ дан Dawood ibn Kareem 16 August 2018 в 01:58
поделиться
  • 1
    Да, Давид прав. Из-за того, как создается API Mockito, невозможно проверить несколько вызовов с той же ссылкой на аргументы. EasyMock может это сделать, потому что он имеет фазу ожидания до запуска производственного кода. Во всяком случае, вместо Answer я использую ArgurmentCaptor и пишу одно или несколько утверждений о конечном состоянии этого списка, то есть с FEST-Assert assertThat(captor.getValue()).contains("A", "B").contains("T", "U"); – Brice 1 February 2012 в 15:33
  • 2
    @Brice - как это будет работать иначе, чем подход Майкла Уэйла? – Dawood ibn Kareem 1 February 2012 в 22:28
  • 3
    Это не так. Это просто другой способ достижения цели тестирования. Потому что большую часть времени вам действительно не нужно проверять промежуточные аргументы, а только то, что произошли некоторые взаимодействия и конечный результат. Хотя я должен сказать, что если у Тома было конкретное требование, тогда согласилось, что это не поможет ему, но тогда в этом случае я бы избегал измененных объектов в моем производственном коде. Похоже, что обмен сообщениями между двумя сотрудниками и сообщениями всегда должен быть неизменным. – Brice 2 February 2012 в 17:15
  • 4
    @Brice, проверяя аргументы, переданные макету, кажется логически неправильным, чтобы соответствовать окончательному состоянию экземпляра, поскольку это не было состояние во время макетного взаимодействия. – Niel de Wet 21 August 2015 в 11:29
  • 5
    @NieldeWet Да, действительно, это целая точка неизменности сообщения между двумя сотрудниками;) – Brice 21 August 2015 в 17:31

Вы не можете вызвать verify() для объекта, который не является mock. Это вы имели в виду?

Bar collaborator = mock(Bar.class); 
Foo sut = spy(new Foo(collaborator));
verify(collaborator).run(expectedList);
0
ответ дан Garrett Hall 16 August 2018 в 01:58
поделиться
  • 1
    Спасибо, код примера имел ошибку, и я исправил его. Это не мой вопрос. Речь идет о возможности проверки аргумента на основе его значения во время вызова метода, а не самого последнего. – Tom Tucker 1 February 2012 в 01:34

Ответ Dawood ibn Kareem работал для меня, но у меня не было примера, также я использую Kotlin и Mockito-Kotlin , поэтому мое решение таково:

class Foo(var mutable: String)

interface Bar {
    fun run(foo: Foo)
}

@Test fun `validate mutable parameter at invocation`() {
    val bar = mock<Bar>()

    var valueAtInvocation: String? = null
    whenever(bar.run(any())).then {
        val foo = it.arguments.first() as Foo
        valueAtInvocation = foo.mutable // Store mutable value as it was at the invocation
        Unit // The answer
    }

    val foo = Foo(mutable = "first")
    bar.run(foo)
    valueAtInvocation isEqualTo "first"

    foo.mutable = "second"
    bar.run(foo)
    valueAtInvocation isEqualTo "second"
}

valueAtInvocation будет представлять значение изменяемого свойства foo.mutable при последнем вызове bar.run(foo). Также возможно делать утверждения в блоке then {}.

1
ответ дан Love 16 August 2018 в 01:58
поделиться

Почему бы вам не попробовать использовать захват аргументов, чтобы получить значение ожидаемого списка, когда он был запущен, и затем вы можете сравнить его.

ArgumentCaptor<List> listCaptor = ArgumentCaptor.forClass(List.class);

verify(collaborator).run(listCaptor.capture());

assertEquals(expectedList, argument.getValue());
-1
ответ дан Michael Wiles 16 August 2018 в 01:58
поделиться
  • 1
    Если ваш измененный список - это тот же самый экземпляр, то аргумент.getValue () вернет экземпляр expectedList, а не копию, так что это по существу то же самое, что и он, не так ли? – jhericks 31 January 2012 в 23:47
  • 2
    @Michael Wiles Спасибо, но, как упоминалось в Jhericks, ArgumentCaptor захватывает исходный экземпляр List. – Tom Tucker 1 February 2012 в 01:31
  • 3
    Извините, Майкл, я отклонил ваш ответ, потому что ваше решение имеет ту же проблему, что и тест OP, как объясняли jhericks. – Dawood ibn Kareem 1 February 2012 в 02:33
Другие вопросы по тегам:

Похожие вопросы: