Mockito: UnlimitedUseOfMatchersException


140

Tôi có một công cụ dòng lệnh thực hiện kiểm tra DNS. Nếu kiểm tra DNS thành công, lệnh sẽ tiếp tục với các tác vụ tiếp theo. Tôi đang cố gắng viết bài kiểm tra đơn vị cho việc này bằng Mockito. Đây là mã của tôi:

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

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

Tôi đang sử dụng InetAddressFactory để giả định một triển khai tĩnh của InetAddresslớp. Đây là mã cho nhà máy:

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

Đây là trường hợp thử nghiệm đơn vị của tôi:

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

Ngoại lệ khi chạy testPostDnsCheck()thử:

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

Bất kỳ đầu vào về làm thế nào để giải quyết điều này?

Câu trả lời:


283

Thông báo lỗi phác thảo giải pháp. Dòng

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

sử dụng một giá trị thô và một công cụ đối sánh, khi cần sử dụng tất cả các giá trị thô hoặc tất cả các công cụ đối sánh. Một phiên bản chính xác có thể đọc

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

8
Tôi thật ngốc nghếch. Tôi tiếp tục phân tích lý do tại sao tham số thứ 2 tiếp tục cho tôi lỗi. Cảm ơn đã làm rõ. Tôi rất mới với Mockito, đây là lần gặp đầu tiên của tôi.
devang

32

Tôi đã có cùng một vấn đề trong một thời gian dài, tôi thường cần phải trộn các Matcher và các giá trị và tôi chưa bao giờ quản lý để làm điều đó với Mockito .... cho đến gần đây! Tôi đặt giải pháp ở đây với hy vọng nó sẽ giúp được ai đó ngay cả khi bài đăng này khá cũ.

Rõ ràng là không thể sử dụng các giá trị Matcher VÀ cùng nhau trong Mockito, nhưng nếu có một Matcher chấp nhận để so sánh một biến thì sao? Điều đó sẽ giải quyết vấn đề ... và trên thực tế có: eq

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

Trong ví dụ này, 'metas' là một danh sách các giá trị hiện có


5
Tuyệt vời. org.mockito.Mockito.eq()
javaPlease42

4
nhập khẩu thích hợp bây giờ là org.mockito.ArgumentMatchers.eq ()
sam

15

Nó có thể giúp một số người trong tương lai: Mockito không hỗ trợ chế giễu các phương pháp 'cuối cùng' (ngay bây giờ). Nó đã cho tôi như vậy InvalidUseOfMatchersException.

Giải pháp cho tôi là đưa một phần của phương pháp không phải là 'cuối cùng' vào một phương thức riêng biệt, có thể truy cập và có thể ghi đè.

Xem lại API Mockito cho trường hợp sử dụng của bạn.


Điều này đã giúp tìm ra lý do tại sao mã kotlin của tôi sẽ gây ra lỗi cho tôi, vì tất cả các phương pháp trong kotlin là cuối cùng!
xin lỗi_I_wont

0

Mặc dù sử dụng tất cả các công cụ đối sánh, tôi cũng gặp vấn đề tương tự:

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

Tôi mất ít thời gian để nhận ra rằng phương thức mà tôi đang cố gắng giả định là một phương thức tĩnh của một lớp (giả sử Xyz. Class) chỉ chứa phương thức tĩnh và tôi đã quên viết dòng sau:

PowerMockito.mockStatic(Xyz.class);

Có thể nó sẽ giúp người khác vì nó cũng có thể là nguyên nhân của vấn đề.


0

Đối với trường hợp của tôi, ngoại lệ được nêu ra vì tôi đã cố gắng chế giễu một package-accessphương pháp. Khi tôi thay đổi cấp độ truy cập phương pháp từ packageđể protectedtrừ đi. Ví dụ: bên trong lớp Java bên dưới

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

phương thức String getName(String id)phải ở mức AT LEAST protected để cơ chế chế tạo (phân lớp phụ) có thể hoạt động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.