Может ли Mockito проверять параметры на основе их значений во время вызова метода? - PullRequest
14 голосов
/ 31 января 2012

У меня есть класс Foo, который является SUT, и класс Bar, который является его соавтором. Foo вызывает run(List<Object> values) на Bar с "expectedList" в качестве аргумента. Затем Foo добавит еще несколько элементов к этому List, так что его состояние будет отличаться от того, которое было на момент вызова run(). Вот мой тестовый пример.

@Test
public void testFoo() {
    Bar collaborator = spy(new Bar()); 
    Foo sut = new Foo(collaborator);
    verify(collaborator).run(expectedList);
}

Обратите внимание, что соавтор на самом деле является объектом шпиона, а не насмешкой. Этот тест не пройдёт, потому что, хотя run() был вызван с аргументом, равным expectedList, он был изменён, и его текущее значение больше не равно expectedList. Тем не менее, это способ, которым он должен работать, поэтому мне интересно, есть ли способ, чтобы Mockito сохранял моментальный снимок параметров при вызове метода и проверял их на основе этих значений, а не самых последних значений.

Ответы [ 4 ]

12 голосов
/ 01 февраля 2012

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

1 голос
/ 30 ноября 2017

Ответ Дауда ибн Карима работал для меня, но мне не хватало примера, также я использую 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 {}.

0 голосов
/ 01 февраля 2012

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

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

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

assertEquals(expectedList, argument.getValue());
0 голосов
/ 01 февраля 2012

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

Bar collaborator = mock(Bar.class); 
Foo sut = spy(new Foo(collaborator));
verify(collaborator).run(expectedList);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...