2013-02-13 28 views
74

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ụ khác. Tôi đang cố gắng viết các bài kiểm tra đơn vị cho việc này bằng cách sử dụng Mockito. Đây là mã của tôi:Mockito: InvalidUseOfMatchersException

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 InetAddressNhà máy để thực thi tĩnh lớp InetAddress. Dưới đây là các mã cho các nhà máy:

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

Dưới đây là đơn vị kiểm tra trường hợp 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ệ trên chạy testPostDnsCheck() kiểm tra:

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ề cách giải quyết này?

Trả lời

156

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

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

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

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

Ngớ ngẩn của tôi. 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 bạ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

+1

Cảm ơn người đàn ông. Thông báo ngoại lệ nếu rất khó hiểu, nhưng lời giải thích của bạn rất rõ ràng để hiểu được –

17

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

Rõ ràng là không thể sử dụng đối sánh và giá trị với nhau trong Mockito, nhưng nếu có một Matcher chấp nhận để so sánh một biến? Điều đó sẽ giải quyết vấn đề ... và trong 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à danh sách hiện tại của giá trị

+4

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

+1

việc nhập phù hợp hiện là org.mockito.ArgumentMatchers.eq() – sam

6

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

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

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