1. ホーム
  2. java

[解決済み] モッキート:InvalidUseOfMatchersException

2022-02-26 23:02:46

質問

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

InetAddressFactoryを使って、静的な実装をモックにしています。 InetAddress クラスがあります。以下は、このファクトリーのコードです。

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

は、すべての raw 値かすべての matcher を使う必要があるにもかかわらず、ひとつの raw 値とひとつの matcher を使っています。正しいバージョンは次のようになります。

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