2013-08-21 13 views
5

farklı parametre ile bir taklidinin çağrıldığında nasıl bir yöntem doğrulamak için farklı parametreler kullanılarak sırayla çağrılan bir mock bir yöntem test etmek istiyorummockito: Aşağıdaki kodu kullanmak</p> <p>Denedim: sırayla

bana bir hata verdi
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")); 

Ancak bu işe görünmüyor

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

8 kez çağrısında kaydedildiği ifade edildi. Bu doğru, ancak siparişi ele almak için başarısız.

ben kontrol etmek istiyorum:

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" 
    ...... 

Bunu nasıl başarabiliriz?

DÜZENLEME:

Hata iletisi:

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

Hataların tam olarak ne söylediğini bize gösterir misiniz? –

+0

Teşekkürler. Hata mesajı eklendi. – KKKCoder

+0

"inOrder.verify (myobject, times (2)). Println (any (String.class));' ile aramayı denediniz mi? –

cevap

5

Tüm println aramalarındaki argümanları yakalamak için bir argüman captor kullanın, sonra ilgilendiğiniz yakalanan değerlerin her birini kontrol edin.

@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

Eh, bu yanıtın çok genel değildir ve ya zarif değildir.

Benim için sorun any(String.class)'un açgözlü olduğu, yani, her türlü dizeyle eşleştiği görülüyor. Bu yüzden, birkaç istisna haricinde her çeşit dizeyle eşleşen bir eşleştirici oluşturmaya çalıştım: "" or "myfolder" or System.getProperty("user.home"). Ve kodudur:

import static org.mockito.AdditionalMatchers.*; 

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

Bu bir meydan okuma kendisi gizemli nedense (bu okunabilir olması biçimlendirmek için, bu mockito bir garip zamanı özel durumuna neden çünkü ben bile yerel bir değişkene and(...) açamadı ben eşleştiriciyi saplama veya doğrulama dışında kullanamazsınız).

3

David Wallace'ın çözümü, Mockito'nun kullandığını bildiğim en iyi çözümdür, ancak bu alayın her zaman iş için doğru araç olmadığını unutmayın.

Yapabilirseniz, alay yerine, bir PrintWriter(ByteArrayOutputStream) geçirin ve ByteArrayOutputStream beklediğiniz çıktının eşleştiğinden emin olun.

@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")); 
} 

Bu aynı zamanda çıkış yöntemleri tam olarak doğru sırayla çağrıldı değil, bunu beklemek şekilde görünüyor ki aslında test ediyoruz mantık, muhtemelen daha yakın. Ardından, MessageFormatter şablonuna geçiş yapmak veya yeni satırlarınızı bir StringBuilder uygulamasına dönüştürmek ve println numaralı telefonu arayarak dahil olmak üzere istediğiniz herhangi bir şekilde yeniden düzenleme yapmakta özgürsünüz. Ayrıca, başka bir print veya println() aramasını kullanan herhangi birinden, bir Mockito tabanlı testi bozacak olanlardan da yalıtılmıştır.

Gereksinimlerinizi doğru olarak belirlemek için gereksinimlerinize bağlı olarak bir regex Pattern veya Scanner kullanabilirsiniz. Pattern.quote, beklenen dizeyi programsal olarak oluşturmanız gerekiyorsa (user.home ile yaptığınız gibi) regex alt dizelerinden kaçmanıza yardımcı olabilir.

+0

+1 Bu test, JMockit Verifications API ile çok güzel yazılabilir, ancak sonuçta bu aşırı kullanım alay konusu; Tam string çıktısını yakalamak ve kontrol etmek iyi yapılandırılmış olabilir, belki bir regex ile çok daha iyi bir çözümdür. –