Mockito가 논쟁에 관계없이 방법을 쓸 수 있습니까?


302

Mockito를 사용하여 일부 레거시 코드를 테스트하려고합니다.

FooDao프로덕션에서 사용되는 a 를 다음과 같이 스텁하고 싶습니다 .

foo = fooDao.getBar(new Bazoo());

난 쓸수있다:

when(fooDao.getBar(new Bazoo())).thenReturn(myFoo);

그러나 명백한 문제는 내가 메서드를 스텁 한 getBar()것과 동일한 Bazoo객체로 호출되지 않는다는 것입니다. (그 new연산자를 저주하십시오 !)

myFoo인수에 관계없이 반환되는 방식으로 메소드를 스텁 할 수 있다면 그것을 좋아할 것 입니다. 실패하면 다른 해결 방법 제안을 듣지 만 합리적인 테스트 적용 범위가 될 때까지 프로덕션 코드를 변경하지 않는 것이 좋습니다.

답변:


456
when(
  fooDao.getBar(
    any(Bazoo.class)
  )
).thenReturn(myFoo);

또는 ( nulls 피하기 위해 ) :

when(
  fooDao.getBar(
    (Bazoo)notNull()
  )
).thenReturn(myFoo);

매처를 가져 오는 것을 잊지 마십시오 (다른 사람도 가능) :

Mockito 2.1.0 이상 :

import static org.mockito.ArgumentMatchers.*;

이전 버전의 경우 :

import static org.mockito.Matchers.*;

2
나는 대답이 '응답 동결 수락'의 끝보다 앞에 오면 그것을 좋아합니다.
Eric Wilson

10
있다 notNull(Bazoo.class)단지처럼 any(Bazoo.class)(어쩌면이 답변의 시간에 존재하지 않았다)
Dandre 앨리슨

2
나는 두 가지 가능한 인수 중 하나를 가질 수 Bazoo있거나 Cazoo두 하위 클래스 인 두 가지 특별한 상황이있었습니다 Azoo. 위해 Bazoo내가 돌아 필요 foo하지만, 위해 Cazoo내가 돌아 필요 bar. 이 상황에서 제안 된 Matchers.any()솔루션은 작동하지 않지만 Matchers.isA()완벽하게 작동합니다.
Tanvir

3
org.mockito.Matchers더 이상 사용되지 않습니다. org.mockito.ArgumentMatchers대신 사용 import static org.mockito.ArgumentMatchers.*하십시오 ( 예 : 문서 참조 )
DontDivideByZero

when(myFoo.knowsWhatsUp()).thenReturn(myMoney);
6rchid

18

다음과 같이 사용하십시오.

when(
  fooDao.getBar(
    Matchers.<Bazoo>any()
  )
).thenReturn(myFoo);

가져 오기 전에 Mockito.Matchers


1
이것은 지원되지 않습니다!
DrB

15

http://site.mockito.org/mockito/docs/1.10.19/org/mockito/Matchers.html

anyObject() 당신의 요구에 맞아야합니다.

또한, 당신은 항상 구현 고려할 수 hashCode()equals()을위한 Bazoo클래스입니다. 그러면 코드 예제가 원하는 방식으로 작동합니다.


두 번째 제안에 동의했지만 비 기술적 인 이유로 여전히 그렇게하지 않기로 결정하고 있습니다.
Eric Wilson

1
매처 (Matchers) 클래스는 사용되지 않습니다 (참조 문서를 - "이 클래스는 가능성이 버전 3.0에서 제거 될 예정입니다" )
요하네스 Rabauer에게

1

또 다른 옵션은 좋은 구식 equals방법 에 의존하는 것 입니다. 오랫동안의 인수로 when모의 equals코드의 인수가 테스트되고, 다음 Mockito는 모의 일치합니다.

다음은 예입니다.

public class MyPojo {

    public MyPojo( String someField ) {
        this.someField = someField;
    }

    private String someField;

    @Override
    public boolean equals( Object o ) {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;
        MyPojo myPojo = ( MyPojo ) o;
        return someField.equals( myPojo.someField );
    }

}

그런 다음, 가치가 무엇인지 알고 있다고 가정하면 다음 someField과 같이 조롱 할 수 있습니다.

when(fooDao.getBar(new MyPojo(expectedSomeField))).thenReturn(myFoo);

찬성 : 이것은보다 명확 any합니다. 코드 검토 자로서 any, 코드 개발자가 작성하는 코드를 살펴보고 코드의 논리를 살펴보고 전달되는 적절한 객체를 생성합니다.

con : 때때로 객체로 전달되는 필드가 임의의 ID입니다. 이 경우 모의 코드에서 예상 인수 객체를 쉽게 구성 할 수 없습니다.

또 다른 가능한 접근 방법은 메소드 Answer와 함께 사용할 수있는 Mockito의 객체를 사용하는 when것입니다. Answer실제 호출을 가로 채고 입력 인수를 검사하고 모의 객체를 반환 할 수 있습니다. 아래 예제 any에서 모의중인 메소드에 대한 요청을 잡기 위해 사용 하고 있습니다. 그러나 Answer람다에서 Bazo 인수를 추가로 검사 할 수 있습니다 ... 아마 적절한 ID가 전달되었는지 확인할 수 있습니다. 나는 any논쟁 자체에 대해 적어도 약간의 조사가 이루어 지도록 이것을 스스로 선호 한다.

    Bar mockBar = //generate mock Bar.

    when(fooDao.getBar(any(Bazo.class))
    .thenAnswer(  ( InvocationOnMock invocationOnMock) -> {
        Bazo actualBazo = invocationOnMock.getArgument( 0 );

        //inspect the actualBazo here and thrw exception if it does not meet your testing requirements.
        return mockBar;
    } );

그래서 결론을 내릴 때 equals(예상되는 인수와 실제 인수가 서로 같아야 함) 의존하는 것이 좋으며 (실제 인수의 상태를 예측할 수 없기 때문에) 등호를 사용할 수없는 경우, 나는 의지 할 것입니다 하는 Answer인수를 검사합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.