[java] mockito를 사용하여 객체 속성 값 확인

mockito로 조롱하려는 메소드 호출이 있습니다. 먼저 메소드를 호출 할 객체의 인스턴스를 생성하고 주입했습니다. 내 목표는 메소드 호출에서 객체 중 하나를 확인하는 것입니다.

mockito를 사용하여 mock 메소드가 호출 될 때 객체와 객체의 속성을 주장하거나 확인할 수있는 방법이 있습니까?

Mockito.verify(mockedObject)
       .someMethodOnMockedObject(
              Mockito.<SomeObjectAsArgument>anyObject())

대신에 anyObject()인수 객체에 특정 필드가 포함되어 있는지 확인하고 싶습니다.

Mockito.verify(mockedObject)
       .someMethodOnMockedObject(
              Mockito.<SomeObjectAsArgument>**compareWithThisObject()**)



답변

Mockito에 추가 된 새로운 기능으로 더욱 쉽게

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

Mockito 문서를 살펴보십시오


하나 이상의 매개 변수가 있고 단일 매개 변수 만 캡처하려는 경우 다른 ArgumentMatchers를 사용하여 나머지 인수를 래핑하십시오.

verify(mock).doSomething(eq(someValue), eq(someOtherValue), argument.capture());
assertEquals("John", argument.getValue().getName());


답변

인수 객체를 확인하는 가장 쉬운 방법은 refEq메소드 를 사용하는 것입니다.

Mockito.verify(mockedObject).someMethodOnMockedObject(Matchers.refEq(objectToCompareWith));

equals()리플렉션이 사용되기 때문에 객체가 구현하지 않아도 사용할 수 있습니다 . 일부 필드를 비교하지 않으려면 해당 필드의 이름을에 대한 인수로 추가하십시오 refEq.


답변

사용하지 않으려는 경우 ArgumentCaptor(예 : 스터 빙도 사용하기 때문에) 햄 크레스트 매처를 Mockito와 함께 사용하는 것이 하나 더 있습니다.

import org.mockito.Mockito
import org.hamcrest.Matchers
...

Mockito.verify(mockedObject).someMethodOnMockedObject(MockitoHamcrest.argThat(
    Matchers.<SomeObjectAsArgument>hasProperty("propertyName", desiredValue)));


답변

이것은 iraSenthil의 답변을 기반으로 하지만 주석 ( Captor ) 이있는 답변입니다 . 내 의견으로는 몇 가지 장점이 있습니다.

  • 더 짧아
  • 읽기 쉽다
  • 경고없이 제네릭을 처리 할 수 ​​있습니다.

예:

@RunWith(MockitoJUnitRunner.class)
public class SomeTest{

    @Captor
    private ArgumentCaptor<List<SomeType>> captor;

    //...

    @Test
    public void shouldTestArgsVals() {
        //...
        verify(mockedObject).someMethodOnMockedObject(captor.capture());

        assertThat(captor.getValue().getXXX(), is("expected"));
    }
}


답변

Java 8을 사용하는 경우 Lambda 표현식을 사용하여 일치시킬 수 있습니다.

import java.util.Optional;
import java.util.function.Predicate;

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;

public class LambdaMatcher<T> extends BaseMatcher<T>
{
    private final Predicate<T> matcher;
    private final Optional<String> description;

    public LambdaMatcher(Predicate<T> matcher)
    {
        this(matcher, null);
    }

    public LambdaMatcher(Predicate<T> matcher, String description)
    {
        this.matcher = matcher;
        this.description = Optional.ofNullable(description);
    }

    @SuppressWarnings("unchecked")
    @Override
    public boolean matches(Object argument)
    {
        return matcher.test((T) argument);
    }

    @Override
    public void describeTo(Description description)
    {
        this.description.ifPresent(description::appendText);
    }
}

호출 예

@Test
public void canFindEmployee()
{
    Employee employee = new Employee("John");
    company.addEmployee(employee);

    verify(mockedDal).registerEmployee(argThat(new LambdaMatcher<>(e -> e.getName()
                                                                         .equals(employee.getName()))));
}

추가 정보 : http://source.coveo.com/2014/10/01/java8-mockito/


답변

위의 솔루션은 실제로 제 경우에는 효과가 없었습니다. 메소드가 여러 번 호출되었으므로 ArgumentCaptor를 사용할 수 없었으며 각 메소드를 검증해야했습니다. “argThat”을 사용하는 간단한 매 처가 트릭을 쉽게 수행했습니다.

커스텀 매처

// custom matcher
private class PolygonMatcher extends ArgumentMatcher<PolygonOptions> {
    private int fillColor;
    public PolygonMatcher(int fillColor) {
        this.fillColor = fillColor;
    }

    @Override
    public boolean matches(Object argument) {
        if (!(argument instanceof PolygonOptions)) return false;
        PolygonOptions arg = (PolygonOptions)argument;
        return Color.red(arg.getFillColor()) == Color.red(fillColor)
                && Color.green(arg.getFillColor()) == Color.green(fillColor)
                && Color.blue(arg.getFillColor()) == Color.blue(fillColor);
    }
}

테스트 러너

// do setup work setup
// 3 light green polygons
int green = getContext().getResources().getColor(R.color.dmb_rx_bucket1);
verify(map, times(3)).addPolygon(argThat(new PolygonMatcher(green)));

// 1 medium yellow polygons
int yellow = getContext().getResources().getColor(R.color.dmb_rx_bucket4);
    verify(map, times(1)).addPolygon(argThat(new PolygonMatcher(yellow)));

// 3 red polygons
int orange = getContext().getResources().getColor(R.color.dmb_rx_bucket5);
verify(map, times(3)).addPolygon(argThat(new PolygonMatcher(orange)));

// 2 red polygons
int red = getContext().getResources().getColor(R.color.dmb_rx_bucket7);
verify(map, times(2)).addPolygon(argThat(new PolygonMatcher(red)));


답변

콜틴의 아주 좋고 깨끗한 해결책은 com.nhaarman.mockito_kotlin

verify(mock).execute(argThat {
    this.param = expected
})