2013-08-21 23 views
5

Tôi muốn thử nghiệm một phương pháp của một mô hình được gọi theo thứ tự sử dụng các thông số khác nhau:Mockito: Làm thế nào để xác minh một phương pháp được gọi là trên một mô hình với tham số khác nhau để

Tôi cố gắng để sử dụng đoạn mã sau:

InOrder inOrder = inOrder(myobject); 
    inOrder.verify(myobject).println(any(String.class)); 
    inOrder.verify(myobject).println(any(String.class)); 
    inOrder.verify(myobject).println(""); 
    inOrder.verify(myobject).println("myfolder"); 
    inOrder.verify(myobject).println(""); 
    inOrder.verify(myobject).println(System.getProperty("user.home")); 

Tuy nhiên, điều này dường như không làm việc vì nó đã cho tôi một lỗi nói

inOrder.verify(myobject).println(any(String.class)); 

đã được kêu gọi 8 lần. Điều này là chính xác, nhưng nó không giải quyết được thứ tự.

Tôi muốn kiểm tra:

The println method of `myobject` is first called with any string parameter 
    Then it is called with any string parameter again 
    Then it is called by an empty string 
    Then it is called by string "myfolder" 
    ...... 

Làm thế nào tôi có thể đạt được điều này?

EDIT:

Thông báo lỗi là:

org.mockito.exceptions.verification.VerificationInOrderFailure: 
Verification in order failure: 
printWriter.println(<any>); 
Wanted 1 time: 
-> at com.mycompany.MyUnitTest.mytest(MyrUnitTest.java:107) 
But was 8 times. 
+0

Bạn có thể cho chúng tôi biết chính xác lỗi được nói không? –

+0

Cảm ơn. Đã thêm thông báo lỗi. – KKKCoder

+0

Bạn đã thử gọi nó bằng 'inOrder.verify (myobject, times (2)). Println (bất kỳ (String.class));'? –

Trả lời

5

Sử dụng trình thu thập đối số để nắm bắt các đối số trong tất cả lệnh gọi đến println, sau đó kiểm tra từng giá trị đã chụp mà bạn quan tâm.

@Captor ArgumentCaptor<String> stringCaptor; 

// ... 

@Test public void myTest() { 

    // ... 

    verify(myobject, 6).println(stringCaptor.capture()); 
    assertEquals("", stringCaptor.getAllValues()[2]); 
    assertEquals("myfolder", stringCaptor.getAllValues()[3]); 
    assertEquals("", stringCaptor.getAllValues()[4]);  
    assertEquals(System.getProperty("user.home"), stringCaptro.getAllValues()[5]); 
1

Vâng, câu trả lời này không phải là quá chung chung, và không phải là tao nhã một trong hai.

Đối với tôi có vẻ như vấn đề là do any(String.class) tham lam, nghĩa là, nó khớp với tất cả các loại chuỗi. Vì vậy, tôi đã cố gắng để chế tạo một matcher phù hợp với tất cả các loại dây ngoại trừ một vài ngoại lệ: "" or "myfolder" or System.getProperty("user.home"). Và mã là:

import static org.mockito.AdditionalMatchers.*; 

inOrder.verify(myobject, times(2)).println(
      and(anyString(), not(
        or(eq(""), or(eq("myfolder"), eq(System.getProperty("user.home"))))))); 

Nó là một thách thức riêng của mình để định dạng này để có thể đọc được (vì một lý do bí ẩn, tôi thậm chí không thể trích xuất and(...) cho một biến địa phương vì nó gây ra một ngoại lệ thời gian chạy lạ từ Mockito mà tôi không thể sử dụng matcher bên ngoài của stubbing hoặc xác minh).

3

Giải pháp của David Wallace là giải pháp tốt nhất mà tôi biết về cách sử dụng Mockito, nhưng hãy nhớ rằng việc nhạo báng không phải lúc nào cũng là công cụ thích hợp cho công việc.

Nếu bạn có thể, thay vì giả lập, hãy chuyển một số PrintWriter(ByteArrayOutputStream) và kiểm tra xem ByteArrayOutputStream có khớp với kết quả bạn mong đợi hay không.

@Test public void yourTest() { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    PrintWriter writer = new PrintWriter(baos); 
    systemUnderTest.doThing(writer); 

    assertTrue(writer.toString().endsWith(
     "\n\nmyfolder\n\n" + System.getProperty(user.home) + "\n")); 
} 

Điều này cũng gần với logic bạn đang thực sự thử nghiệm, đó là đầu ra trông giống như cách bạn mong đợi, không phải là phương thức được gọi đúng thứ tự đúng. Sau đó, bạn được tự do tái cấu trúc theo bất kỳ cách nào bạn muốn, bao gồm chuyển sang mẫu MessageFormatter hoặc xây dựng các dòng mới của bạn thành một StringBuilder và gọi println một lần. Bạn cũng được cách ly với bất kỳ ai sử dụng bất kỳ cuộc gọi nào khác print hoặc println(), điều này sẽ làm sai lệch một thử nghiệm dựa trên Mockito.

Bạn cũng có thể sử dụng regex Pattern hoặc Scanner để xác minh tính chính xác, tùy thuộc vào nhu cầu cụ thể của bạn. Pattern.quote có thể giúp bạn thoát khỏi các phân đoạn regex nếu bạn cần xây dựng chuỗi dự kiến ​​của bạn theo chương trình (như bạn làm với user.home tại đây).

+0

+1 Thử nghiệm này có thể được viết rất độc đáo với API xác minh JMockit, nhưng cuối cùng, đây là trường hợp chế nhạo quá mức; nắm bắt đầu ra chuỗi đầy đủ và kiểm tra nó cũng được hình thành, có lẽ với một regex, là một giải pháp tốt hơn nhiều. –

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