[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
})