[java] 모키 토 : InvalidUseOfMatchersException

DNS 확인을 수행하는 명령 줄 도구가 있습니다. DNS 확인에 성공하면 명령은 추가 작업을 진행합니다. Mockito를 사용하여 단위 테스트를 작성하려고합니다. 내 코드는 다음과 같습니다.

public class Command() {
    // ....
    void runCommand() {
        // ..
        dnsCheck(hostname, new InetAddressFactory());
        // ..
        // do other stuff after dnsCheck
    }

    void dnsCheck(String hostname, InetAddressFactory factory) {
        // calls to verify hostname
    }
}

InetAddress클래스 의 정적 구현을 ​​조롱하기 위해 InetAddressFactory를 사용하고 있습니다. 공장 코드는 다음과 같습니다.

public class InetAddressFactory {
    public InetAddress getByName(String host) throws UnknownHostException {
        return InetAddress.getByName(host);
    }
}

내 단위 테스트 사례는 다음과 같습니다.

@RunWith(MockitoJUnitRunner.class)
public class CmdTest {

    // many functional tests for dnsCheck

    // here's the piece of code that is failing
    // in this test I want to test the rest of the code (i.e. after dnsCheck)
    @Test
    void testPostDnsCheck() {
        final Cmd cmd = spy(new Cmd());

        // this line does not work, and it throws the exception below:
        // tried using (InetAddressFactory) anyObject()
        doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class));
        cmd.runCommand();
    }
}

testPostDnsCheck()테스트 실행시 예외 :

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected, 1 recorded.
This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

이 문제를 해결하는 방법에 대한 의견이 있으십니까?



답변

오류 메시지는 솔루션을 간략하게 설명합니다. 라인

doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class))

모든 원시 값 또는 모든 매처를 사용해야하는 경우 하나의 원시 값과 하나의 매처를 사용합니다. 올바른 버전이 읽을 수 있습니다

doNothing().when(cmd).dnsCheck(eq(HOST), any(InetAddressFactory.class))


답변

나는 오랫동안 같은 문제를 겪었고, 종종 Matcher와 value를 혼합해야했고 Mockito와는 결코 그렇게하지 못했습니다 …. 최근까지! 이 게시물이 아주 오래된 경우에도 누군가에게 도움이되기를 바랍니다.

Mockito에서 Matchers AND 값을 함께 사용할 수는 없지만 변수를 비교할 수있는 Matcher가 있다면 어떨까요? 문제를 해결할 것입니다 … 실제로는 : eq

when(recommendedAccessor.searchRecommendedHolidaysProduct(eq(metas), any(List.class), any(HotelsBoardBasisType.class), any(Config.class)))
            .thenReturn(recommendedResults);

이 예에서 ‘metas’는 기존 값 목록입니다.


답변

Mockito는 ‘최종’방법의 조롱 (현재)을 지원하지 않습니다. 그것은 나에게 같은 것을 주었다 InvalidUseOfMatchersException.

나를위한 해결책은 ‘최종’일 필요가없는 방법의 일부를 별도의 액세스 가능하고 재정의 가능한 방법으로 넣는 것이 었습니다.

사용 사례에 대한 Mockito API 를 검토하십시오 .


답변

모든 매처를 사용하더라도 동일한 문제가 발생했습니다.

"org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
1 matchers expected, 3 recorded:"

내가 조롱하려고 한 메소드가 정적 메소드 만 포함하는 클래스 (예 : Xyz.class)의 정적 메소드였으며 다음 줄을 쓰는 것을 잊어 버렸습니다.

PowerMockito.mockStatic(Xyz.class);

문제의 원인 일 수도 있으므로 다른 사람들을 도울 수 있습니다.


답변

필자의 경우 package-access메서드 를 조롱하려고했기 때문에 예외가 발생했습니다 . 나는에서 메소드 액세스 수준을 변경하는 경우 packageprotected예외가 멀리 갔다. 예를 들어 Java 클래스 아래에서

public class Foo {
    String getName(String id) {
        return mMap.get(id);
    }
}

이 방법 String getName(String id)은 조롱 메커니즘 (서브 클래 싱)이 작동 할 수 있도록 최소 protected 수준 이어야 합니다.


답변