2012-05-31 26 views
24

Có thể chặn tất cả các lời gọi phương thức trên một mô hình theo cách chung chung không?Mockito - chặn bất kỳ lời gọi phương thức nào trên mô hình

Ví dụ

Cho một nhà cung cấp cung cấp lớp như:

public class VendorObject { 

    public int someIntMethod() { 
     // ... 
    } 

    public String someStringMethod() { 
     // ... 
    } 

} 

Tôi muốn tạo ra một mô hình mà lại chỉ đạo tất cả phương pháp các cuộc gọi đến một lớp học, nơi có những phương thức khớp chữ ký:

public class RedirectedToObject { 

    public int someIntMethod() { 
     // Accepts re-direct 
    } 

} 

Cấu trúc when(). thenAnswer() t trong Mockito dường như phù hợp với các hóa đơn nhưng tôi không thể tìm thấy một cách để phù hợp với bất kỳ cuộc gọi phương pháp với bất kỳ args. InvocationOnMock chắc chắn mang lại cho tôi tất cả những chi tiết này anyway. Có cách nào chung để làm điều này? Cái gì đó sẽ trông như thế này, nơi mà khi được thay thế bằng mã thích hợp (vo *.):

VendorObject vo = mock(VendorObject.class); 
when(vo.anyMethod(anyArgs)).thenAnswer(
    new Answer() { 
     @Override 
     public Object answer(InvocationOnMock invocation) { 

      // 1. Check if method exists on RedirectToObject. 
      // 2a. If it does, call the method with the args and return the result. 
      // 2b. If it does not, throw an exception to fail the unit test. 

     } 
    } 
); 

wrappers Thêm quanh lớp nhà cung cấp để thực hiện chế giễu dễ dàng không phải là một lựa chọn vì:

  1. Quá lớn cơ sở mã hiện có.
  2. Một phần của các ứng dụng quan trọng cực kỳ hiệu suất.
+0

Đừng nói với tôi nó đơn giản như khi nào (vo) .thenAnswer (...): O – Karle

+0

"Một phần của các ứng dụng quan trọng cực kỳ hiệu suất." Làm thế nào để thêm một đối tượng giả/proxy bất kỳ khác với việc thêm một wrapper trong trường hợp này? Bạn có quan tâm đến việc này chỉ để thử nghiệm đơn vị hay trong ứng dụng thực tế không? –

+0

@mattb: Khía cạnh hiệu suất không phải là đối số lớn nhất chống lại việc sử dụng các lớp bao bọc. Chúng tôi sẽ tạo một giao diện dựa trên đối tượng nhà cung cấp ban đầu và một lớp triển khai chuyển tiếp các yêu cầu đến đối tượng nhà cung cấp thực tế. Thời gian thực hiện cho việc này sẽ nhỏ hơn so với đối tượng nhà cung cấp thực tế đang thực hiện công việc của nó. Đối số quan trọng hơn là cơ sở mã hiện có bằng cách sử dụng trực tiếp đối tượng nhà cung cấp. – Karle

Trả lời

39

Tôi nghĩ rằng những gì bạn muốn là:

VendorObject vo = mock(VendorObject.class, new Answer() { 
    @Override 
    public Object answer(InvocationOnMock invocation) { 

     // 1. Check if method exists on RedirectToObject. 
     // 2a. If it does, call the method with the args and return the 
     // result. 
     // 2b. If it does not, throw an exception to fail the unit test. 

    } 
}); 

Tất nhiên, nếu bạn muốn sử dụng phương pháp này thường xuyên, không có nhu cầu sử dụng trả lời được ẩn danh.

Từ documentation: "Đây là tính năng khá nâng cao và thông thường bạn không cần nó để viết các bài kiểm tra phong nha. Tuy nhiên, có thể hữu ích khi làm việc với các hệ thống cũ". Nghe giống bạn.

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