2011-03-28 3 views
39

Có một phương thức chung để lấy một lớp làm tham số và tôi gặp vấn đề khi đưa nó vào Mockito. Phương pháp này trông như thế này:Đặt một phương thức lấy Class <T> làm tham số với Mockito

public <U extends Enum<U> & Error, T extends ServiceResponse<U>> T validate(
    Object target, Validator validator, Class<T> responseClass, 
    Class<U> errorEnum); 

Đó là thần khủng khiếp, ít nhất là với tôi ... Tôi có thể tưởng tượng cuộc sống mà không có nó, nhưng phần còn lại của cơ sở mã vui vẻ sử dụng nó ...

tôi trong bài kiểm tra đơn vị của tôi, khai báo phương thức này để trả về một đối tượng trống mới. Nhưng làm thế nào để tôi làm điều này với mockito? Tôi cố gắng:

nhưng kể từ khi tôi đang trộn và kết hợp quẹt giá trị liệu, tôi nhận được "org.mockito.exceptions.misusing.InvalidUseOfMatchersException: sử dụng không hợp lệ của quẹt tranh luận"

Trả lời

71

Vấn đề là, bạn không thể kết hợp đối sánh đối số và đối số thực trong cuộc gọi giả. Vì vậy, thay vì làm điều này:

when(serviceValidatorStub.validate(
    any(), 
    isA(UserCommentRequestValidator.class), 
    eq(UserCommentResponse.class), 
    eq(UserCommentError.class)) 
).thenReturn(new UserCommentResponse()); 

Lưu ý việc sử dụng đối sánh đối sánh eq() để đối sánh bình đẳng.

xem: https://static.javadoc.io/org.mockito/mockito-core/1.10.19/org/mockito/Matchers.html#eq(T)

Ngoài ra, bạn có thể sử dụng các khớp same() luận cho Class<?> loại - điều này phù hợp với cùng một bản sắc, giống như các nhà điều hành Java ==.

+0

làm việc như một nét duyên dáng, rất thoải mái trả lời. Cũng giải thích quá –

+0

Mighty biết ơn! –

+0

Thật vậy. Nhưng tôi tự hỏi nếu Mockito có thể được cải thiện để cho phép người dùng "trộn đối sánh đối số và đối số thực sự"; nếu Unitils Mock có thể làm được, thì nó có thể về mặt kỹ thuật. –

2

Chỉ để hoàn thành trên cùng một chuỗi, nếu ai đó muốn đặt một phương thức lấy đối số Lớp làm đối số, nhưng không quan tâm đến loại hoặc cần nhiều loại để được phân tích theo cùng một cách, dưới đây là một giải pháp:

private class AnyClassMatcher extends ArgumentMatcher<Class<?>> { 

    @Override 
    public boolean matches(final Object argument) { 
     // We always return true, because we want to acknowledge all class types 
     return true; 
    } 

} 

private Class<?> anyClass() { 
    return Mockito.argThat(new AnyClassMatcher()); 
} 

và sau đó gọi

Mockito.when(mock.doIt(this.anyClass())).thenCallRealMethod(); 
0

Nice one @Ash. Tôi đã sử dụng matcher lớp chung của bạn để chuẩn bị bên dưới. Điều này có thể được sử dụng nếu chúng tôi muốn chuẩn bị nhạo báng của một loại cụ thể (không dụ)

private Class<StreamSource> streamSourceClass() { 
    return Mockito.argThat(new ArgumentMatcher<Class<StreamSource>>() { 

     @Override 
     public boolean matches(Object argument) { 
      // TODO Auto-generated method stub 
      return false; 
     } 
    }); 
} 

Cách sử dụng:.

Mockito.when(restTemplate.getForObject(Mockito.anyString(), 
      **streamSourceClass(),** 
      Mockito.anyObject));