2015-06-17 22 views
18

Tôi đang bối rối về sự khác biệt giữa chúng là gì, và cái nào để chọn trong trường hợp nào. Một số khác biệt có thể hiển nhiên, như anyeq, nhưng tôi chỉ bao gồm tất cả những điều đó để đảm bảo.Sự khác nhau giữa Mockito Matchers là gì, bất kỳ, eq và giống nhau?

Tôi tự hỏi về sự khác biệt của họ, vì tôi đã xem qua vấn đề này: tôi có phương thức POST này trong một lớp điều khiển

public Response doSomething(@ResponseBody Request request) { 
    return someService.doSomething(request); 
} 

Và muốn thực hiện một thử nghiệm đơn vị trên bộ điều khiển đó. Tôi có hai phiên bản. Người đầu tiên là một trong những đơn giản, như thế này

@Test 
public void testDoSomething() { 
    //initialize ObjectMapper mapper 
    //initialize Request req and Response res 

    when(someServiceMock.doSomething(req)).thenReturn(res); 

    Response actualRes = someController.doSomething(req); 
    assertThat(actualRes, is(res)); 
} 

Nhưng tôi muốn sử dụng một cách tiếp cận MockMvc, như thế này một

@Test 
public void testDoSomething() { 
    //initialize ObjectMapper mapper 
    //initialize Request req and Response res 

    when(someServiceMock.doSomething(any(Request.class))).thenReturn(res); 

    mockMvc.perform(post("/do/something") 
      .contentType(MediaType.APPLICATION_JSON) 
      .content(mapper.writeValueAsString(req)) 
    ) 
      .andExpect(status().isOk()) 
      .andExpect(jsonPath("$message", is("done"))); 
} 

Cả hai làm việc tốt. Nhưng tôi muốn someServiceMock.doSomething() trong phương pháp MockMvc để nhận req hoặc ít nhất một đối tượng có cùng giá trị biến là req (không chỉ bất kỳ lớp nào Request) và trả lại res, giống như lần đầu tiên. Tôi biết rằng nó không thể sử dụng cách tiếp cận MockMvc (hoặc là nó?), Bởi vì đối tượng được thông qua trong các cuộc gọi thực tế là luôn luôn khác nhau từ các đối tượng được thông qua trong mô hình. Có anyway tôi có thể đạt được điều đó? Hay nó có ý nghĩa để làm điều đó? Hoặc tôi có nên hài lòng khi sử dụng any(Request.class) không? Tôi đã thử eq, same, nhưng tất cả đều không thành công.

Cảm ơn bạn trước. Tôi hy vọng tôi đã giải thích tốt cho bản thân mình.

Trả lời

40
  • any() kiểm tra hoàn toàn không có gì. Trong Mockito 1.x, any(T.class) cũng kiểm tra hoàn toàn không có gì nhưng cũng giúp bạn tiết kiệm một diễn viên (trước Java 8).

    This is due to change in Mockito 2.0 and beyond, khi any(T.class) sẽ chia sẻ isA ngữ nghĩa có nghĩa là "bất kỳ T" hay đúng "bất kỳ trường hợp loại T". any() vẫn sẽ kiểm tra hoàn toàn không có gì.

  • isA(T.class) kiểm tra đối số instanceof T, ngụ ý rằng đối số là không null.

  • same(obj) kiểm tra xem đối số có cùng trường hợp như obj không, chẳng hạn như arg == obj là đúng.

  • eq(obj) kiểm tra xem đối số bằng obj theo phương thức equals của nó hay không. Đây cũng là hành vi nếu bạn vượt qua các giá trị thực mà không sử dụng đối sánh.

    Lưu ý rằng trừ khi equals bị ghi đè, bạn sẽ thấy việc thực thi Object.equals mặc định, có hành vi tương tự như same(obj).

Nếu bạn cần chỉnh chính xác hơn, bạn có thể sử dụng một bộ chuyển đổi cho vị ngữ của riêng bạn:

  • Đối Mockito 1.x, sử dụng argThat với một hamcrest Matcher<T> tùy chỉnh mà chọn chính xác các đối tượng bạn cần .
  • Đối với Mockito 2.0 trở lên, hãy sử dụng Matchers.argThat với tùy chỉnh org.mockito.ArgumentMatcher<T> hoặc MockitoHamcrest.argThat với tùy chỉnh Hamcrest Matcher<T>.
2

Nếu cụ Request.class của bạn bằng, sau đó bạn có thể sử dụng eq():

Bar bar = getBar(); 
when(fooService.fooFxn(eq(bar)).then... 

Trên đây khi sẽ kích hoạt trên

fooService.fooFxn(otherBar); 

nếu

otherBar.equals(bar); 

Ngoài ra, nếu bạn muốn giả lập làm việc cho một số tập hợp con khác của inpu t (ví dụ, tất cả các Bar với Bar.getBarLength()> 10), bạn có thể tạo một Matcher. Tôi không thấy mô hình này quá thường xuyên, vì vậy tôi thường tạo ra các Matcher như là một lớp riêng:

private static class BarMatcher extends BaseMatcher<Bar>{ 
...//constructors, descriptions, etc. 
    public boolean matches(Object otherBar){ 
    //Checks, casts, etc. 
    return otherBar.getBarLength()>10; 
    } 
} 

Sau đó, bạn sẽ sử dụng khớp này như sau:

when(fooService.fooFxn(argThat(new BarMatcher())).then... 

Hy vọng rằng sẽ giúp!

Các vấn đề liên quan