2013-02-04 34 views
8

Tôi viết một bài kiểm tra đơn vị cho một lớp FizzConfigurator trông giống như:Mocking một phương pháp Spy với Mockito

public class FizzConfigurator { 
    public void doFoo(String msg) { 
     doWidget(msg, Config.ALWAYS); 
    } 

    public void doBar(String msg) { 
     doWidget(msg, Config.NEVER); 
    } 

    public void doBuzz(String msg) { 
     doWidget(msg, Config.SOMETIMES); 
    } 

    public void doWidget(String msg, Config cfg) { 
     // Does a bunch of stuff and hits a database. 
    } 
} 

Tôi muốn viết một bài kiểm tra đơn vị đơn giản mà khai phương pháp doWidget(String,Config) (để nó doesn thực sự không kích hoạt và nhấn vào cơ sở dữ liệu), nhưng điều đó cho phép tôi xác minh gọi số doBuzz(String) kết thúc bằng cách thực hiện doWidget. Mockito có vẻ như là công cụ thích hợp cho công việc ở đây.

public class FizzConfiguratorTest { 
    @Test 
    public void callingDoBuzzAlsoCallsDoWidget() { 
     FizzConfigurator fixture = Mockito.spy(new FizzConfigurator()); 
     Mockito.when(fixture.doWidget(Mockito.anyString(), Config.ALWAYS)). 
      thenThrow(new RuntimeException()); 

     try { 
      fixture.doBuzz("This should throw."); 

      // We should never get here. Calling doBuzz should invoke our 
      // stubbed doWidget, which throws an exception. 
      Assert.fail(); 
     } catch(RuntimeException rte) { 
      return; // Test passed. 
     } 
    } 
} 

Điều này có vẻ giống như một gameplan tốt (với tôi ít nhất). Nhưng khi tôi thực sự đi để mã nó lên, tôi nhận được lỗi trình biên dịch sau trên dòng thứ 2 bên trong phương pháp thử nghiệm (Mockito.when(...) dòng:

Phương pháp khi (T) trong loại Mockito không áp dụng cho . đối số (void)

tôi thấy rằng Mockito không thể thử một phương thức trả void Vì vậy, tôi hỏi:

  1. tôi tiếp cận thiết lập thử nghiệm này một cách chính xác Hoặc là có một tốt hơn, Mockito-? đề nghị, cách kiểm tra doBuzz gọi doWidget dưới mui xe? Và
  2. Tôi có thể làm gì với việc chế nhạo/stubbing doWidget vì đây là phương pháp quan trọng nhất trong toàn bộ lớp học FizzConfigurator của tôi?

Trả lời

19

Tôi sẽ không sử dụng ngoại lệ để kiểm tra điều đó, nhưng xác minh. Và một vấn đề khác là bạn không thể sử dụng when() với các phương thức trả lại khoảng trống.

Đây là cách tôi sẽ làm điều đó:

FizzConfigurator fixture = Mockito.spy(new FizzConfigurator()); 
doNothing().when(fixture).doWidget(Mockito.anyString(), Mockito.<Config>any())); 
fixture.doBuzz("some string"); 
Mockito.verify(fixture).doWidget("some string", Config.SOMETIMES); 
+3

Một vấn đề khác là không thể sử dụng 'when()' trên gián điệp - hãy xem tài liệu Mockito về [sử dụng gián điệp] (http://docs.mockito.googlecode.com/hg/latest/org /mockito/Mockito.html#13) (lưu ý hình ảnh xác thực) và [phương thức do *] (http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#12). – dj18

+0

Và kiểm tra xem cuộc gọi có thực hiện ['' Mockito.reset''] hay không (http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#17) đã lẻn vào mã của bạn - giả mạo tương tác và cứng đầu. – phineas

0

Đây là một dấu hiệu rõ ràng rằng doWidget phương pháp phải thuộc về một lớp học mà FizzConfigurator sẽ phụ thuộc vào.

Trong thử nghiệm của bạn, phụ thuộc mới này sẽ là một mô hình và bạn có thể dễ dàng xác minh xem phương thức của nó có được gọi là verify hay không.

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