Mockito.Проверьте аргументы метода - PullRequest
169 голосов
/ 24 августа 2010

Я гуглил по этому поводу, но не нашел ничего подходящего. У меня есть что-то вроде этого:

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj )).thenReturn(null);

Testeable testableObj = new Testeable();
testableObj.setMockeable(mock);
command.runtestmethod();

Теперь я хочу убедиться, что mymethod(Object o), который вызывается внутри runtestmethod(), был вызван с объектом o, а не любым другим. Но я всегда сдаю тест, независимо от того, что я ставлю на проверку, например, с:

Mockito.verify(mock.mymethod(Mockito.eq(obj)));

или

Mockito.verify(mock.mymethod(Mockito.eq(null)));

или

Mockito.verify(mock.mymethod(Mockito.eq("something_else")));

Я всегда сдаю тест. Как я могу выполнить эту проверку (если это возможно)?

Спасибо.

Ответы [ 8 ]

250 голосов
/ 19 августа 2015

Альтернативой ArgumentMatcher является ArgumentCaptor.

Официальный пример:

ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());

Захват также можно определить с помощью @Captor аннотация:

@Captor ArgumentCaptor<Person> captor;
//... MockitoAnnotations.initMocks(this);
@Test public void test() {
    //...
    verify(mock).doSomething(captor.capture());
    assertEquals("John", captor.getValue().getName());
}
58 голосов
/ 02 марта 2013

Вы пытаетесь сделать логическое равенство, используя метод объекта .equals?Вы можете сделать это, используя argThat matcher, который включен в Mockito

import static org.mockito.Matchers.argThat

Далее вы можете реализовать свой собственный аргумент matcher, который будет откладывать для каждого объекта .equals метод

private class ObjectEqualityArgumentMatcher<T> extends ArgumentMatcher<T> {
    T thisObject;

    public ObjectEqualityArgumentMatcher(T thisObject) {
        this.thisObject = thisObject;
    }

    @Override
    public boolean matches(Object argument) {
        return thisObject.equals(argument);
    }
}

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

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj)).thenReturn(null);

Testeable obj = new Testeable();
obj.setMockeable(mock);
command.runtestmethod();

verify(mock).mymethod(argThat(new ObjectEqualityArgumentMatcher<Object>(obj)));

Если вы просто хотите получить ТОЧНОЕ равенство (тот же объект в памяти), просто выполните

verify(mock).mymethod(obj);

Это подтвердит этобыл вызван один раз.

46 голосов
/ 24 августа 2010
  • Вам не нужен eq сопоставитель, если вы не используете другие сопоставители.
  • Вы не используете правильный синтаксис - ваш вызов метода должен быть за пределами .verify(mock). Теперь вы инициируете проверку результата вызова метода, ничего не проверяя (не вызывая метод). Следовательно, все тесты проходят.

Ваш код должен выглядеть так:

Mockito.verify(mock).mymethod(obj);
Mockito.verify(mock).mymethod(null);
Mockito.verify(mock).mymethod("something_else");
5 голосов
/ 21 ноября 2017

Я использовал Mockito.verify таким образом

@UnitTest
public class JUnitServiceTest
{
    @Mock
    private MyCustomService myCustomService;


    @Test
    public void testVerifyMethod()
    {
       Mockito.verify(myCustomService, Mockito.never()).mymethod(parameters); // method will never call (an alternative can be pick to use times(0))
       Mockito.verify(myCustomService, Mockito.times(2)).mymethod(parameters); // method will call for 2 times
       Mockito.verify(myCustomService, Mockito.atLeastOnce()).mymethod(parameters); // method will call atleast 1 time
       Mockito.verify(myCustomService, Mockito.atLeast(2)).mymethod(parameters); // method will call atleast 2 times
       Mockito.verify(myCustomService, Mockito.atMost(3)).mymethod(parameters); // method will call at most 3 times
       Mockito.verify(myCustomService, Mockito.only()).mymethod(parameters); //   no other method called except this
    }
}
4 голосов
/ 08 марта 2016

Другой метод заключается в использовании метода org.mockito.internal.matchers.Equals.Equals вместо его переопределения:

verify(myMock).myMethod((inputObject)Mockito.argThat(new Equals(inputObjectWanted)));
4 голосов
/ 02 марта 2012

Вы проверяли метод equals для фиктивного класса?Если этот метод возвращает всегда значение true или вы проверяете один и тот же экземпляр на одном и том же экземпляре и метод равных не перезаписывается (и поэтому проверяет только ссылки), он возвращает значение true.

1 голос
/ 03 июля 2015

Вы пробовали это с тем же () совпадением? Как в:

verify(mockObj).someMethod(same(specificInstance));

У меня была такая же проблема. Я пробовал это с помощью eq () matcher, а также refEq (), но у меня всегда были ложные срабатывания. Когда я использовал тот же () matcher, тест не удался, когда аргументы были разными экземплярами, и проходил, когда аргументы были одним и тем же экземпляром.

0 голосов
/ 17 февраля 2016

Вы также можете использовать TypeSafeDiagnosingMatcher

    private Matcher<GetPackagesRequest> expectedPackageRequest(final AvailabilityRequest request) {
    return new TypeSafeDiagnosingMatcher<GetPackagesRequest>() {

        StringBuilder text = new StringBuilder(500);

        @Override
        protected boolean matchesSafely(GetPackagesRequest req, Description desc) {
            String productCode = req.getPackageIds().iterator().next().getValue();
            if (productCode.equals(request.getSupplierProductCode())) {
                text.append("ProductCode not equal! " + productCode + " , " + request.getSupplierProductCode());
                return true;
            }

            text.append(req.toString());
            return false;
        }

        @Override
        public void describeTo(Description d) {
            d.appendText(text.toString());
        }
    };
}

Затем убедитесь, что вызов:

Mockito.verify(client).getPackages(Mockito.argThat(expectedPackageRequest(request)));
...