Mockito: InvalidUseOfMatchersException

145

Saya memiliki alat baris perintah yang melakukan pemeriksaan DNS. Jika pemeriksaan DNS berhasil, perintah dilanjutkan dengan tugas lebih lanjut. Saya mencoba menulis pengujian unit untuk ini menggunakan Mockito. Ini kode saya:

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

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

Saya menggunakan InetAddressFactory untuk mengejek implementasi statis InetAddresskelas. Berikut kode pabriknya:

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

Inilah kasus uji unit saya:

@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();
    }
}

Pengecualian untuk menjalankan testPostDnsCheck()tes:

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

Ada masukan tentang cara mengatasi ini?

devang
sumber

Jawaban:

290

Pesan kesalahan menguraikan solusinya. Garis

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

menggunakan satu nilai mentah dan satu pencocokan, jika diperlukan untuk menggunakan semua nilai mentah atau semua pencocokan. Versi yang benar mungkin terbaca

doNothing().when(cmd).dnsCheck(eq(HOST), any(InetAddressFactory.class))
Ryan Stewart
sumber
8
Betapa konyolnya aku. Saya terus menganalisis mengapa parameter ke-2 terus memberi saya kesalahan. Terima kasih telah menjelaskan. Saya sangat baru mengenal Mockito, ini adalah pertemuan pertama saya.
devang
32

Saya memiliki masalah yang sama untuk waktu yang lama sekarang, saya sering perlu mencampur Matcher dan nilai-nilai dan saya tidak pernah berhasil melakukannya dengan Mockito .... hingga saat ini! Saya meletakkan solusi di sini berharap itu akan membantu seseorang meskipun posting ini sudah cukup lama.

Jelas tidak mungkin untuk menggunakan Matcher DAN nilai bersama-sama di Mockito, tetapi bagaimana jika ada Matcher yang menerima untuk membandingkan variabel? Itu akan memecahkan masalah ... dan sebenarnya ada: persamaan

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

Dalam contoh ini, 'metas' adalah daftar nilai yang ada

sam
sumber
5
Hebat. org.mockito.Mockito.eq()
javaPlease42
4
impor yang tepat sekarang org.mockito.ArgumentMatchers.eq ()
sam
16

Ini mungkin membantu seseorang di masa depan: Mockito tidak mendukung mengejek metode 'terakhir' (sekarang). Itu memberi saya hal yang sama InvalidUseOfMatchersException.

Solusi bagi saya adalah menempatkan bagian dari metode yang tidak harus 'final' dalam metode yang terpisah, dapat diakses, dan dapat diganti.

Tinjau Mockito API untuk kasus penggunaan Anda.

delucasvb.dll
sumber
Ini membantu dalam mencari tahu mengapa kode kotlin saya akan memberi saya kesalahan, karena semua metode di kotlin sudah final!
sorry_I_wont
Luar biasa terima kasih
Michael W
0

Meskipun menggunakan semua matcher, saya mendapatkan masalah yang sama:

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

Butuh sedikit waktu bagi saya untuk mengetahui bahwa metode yang saya coba tiru adalah metode statis kelas (katakanlah Xyz.class) yang hanya berisi metode statis dan saya lupa menulis baris berikut:

PowerMockito.mockStatic(Xyz.class);

Mungkin itu akan membantu orang lain karena mungkin juga menjadi penyebab masalah.

S Kumar
sumber
0

Untuk kasus saya, pengecualian dimunculkan karena saya mencoba mengejek suatu package-accessmetode. Ketika saya mengubah tingkat akses metode dari packageke protectedpengecualian pergi. Misalnya di dalam kelas di bawah Java,

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

metode String getName(String id)tersebut harus SETIDAKNYA pada protected level sehingga mekanisme mocking (sub-classing) dapat bekerja.

shizhen
sumber
-1

Jangan gunakan Mockito.anyXXXX (). Berikan nilai secara langsung ke parameter metode berjenis sama. Contoh:

A expected = new A(10);

String firstId = "10w";
String secondId = "20s";
String product = "Test";
String type = "type2";
Mockito.when(service.getTestData(firstId, secondId, product,type)).thenReturn(expected);

public class A{
   int a ;
   public A(int a) {
      this.a = a;
   }
}
Dinesh Kumar
sumber