Saplama için ArgumentCaptor nasıl kullanılır?


161

Mockito belgelerinde ve javadoklarda diyor ki

ArgumentCaptor'ı doğrulama ile kullanmanız önerilir ancak stubbing ile kullanılmaz.

ancak ArgumentCaptor'un stubbing için nasıl kullanılabileceğini anlamıyorum. Birisi yukarıdaki ifadeyi açıklayabilir ve ArgumentCaptor'un stubbing için nasıl kullanılabileceğini gösterebilir veya nasıl yapılabileceğini gösteren bir bağlantı sağlayabilir mi?


1
Süper kısa ve güzel açıklama burada: dzone.com/articles/…
Benj

Yanıtlar:


271

Test etmek için aşağıdaki yöntemi varsayarsak:

public boolean doSomething(SomeClass arg);

Mockito dokümantasyon sen gerektiğini söylüyor değil bu şekilde esir kullanın:

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
assertThat(argumentCaptor.getValue(), equalTo(expected));

Çünkü kibrit sırasında eşleştiriciyi kullanabilirsiniz:

when(someObject.doSomething(eq(expected))).thenReturn(true);

Ancak doğrulama farklı bir hikaye. Testinizin bu yöntemin belirli bir argümanla çağrıldığından emin olması gerekiyorsa, kullanın ArgumentCaptorve bunun için tasarlandığı durum budur:

ArgumentCaptor<SomeClass> argumentCaptor = ArgumentCaptor.forClass(SomeClass.class);
verify(someObject).doSomething(argumentCaptor.capture());
assertThat(argumentCaptor.getValue(), equalTo(expected));

Cevap için teşekkürler. Bir sorum var. Üçüncü kod bloğunda true değerinin yalnızca doSomething öğesine iletildiğinde beklenen döndürüldüğünü biliyoruz . Fakat ikinci kod bloğunda true ne zaman döndürülür? Yoksa someObject, bu durumda someMethod için her zaman true döndürür mü?
Can not Tell

Hm, "Ama üçüncü kod bloğunda doğru ne zaman döndürülür ?" Demek istediğinize inanıyorum . Üçüncü kod bloğunda dönüş değerini umursamıyoruz ve varsayılan değer olmasına izin veriyoruz. Boole için öyle falsedeğil true.
Rorick

Hayır tüm gri arka plan bloklarını kod bloğu olarak saydım. İlk bir astar dahil. Hatta atıfta bulunuyordum(SomeObject.doSomething (argumentCaptor.capture ()))) bulundum. ThenReturn (true);
Can not Tell

Ah Üzgünüm. Evet, bu durumda doğru her zaman iade edilecektir.
Rorick

3
emin değilim "stubbing ile kullanmama" basit bir nedendir. eşleştiriciler bize gerçek beklenen argümanı (sadece tür) vermez ve yanlış olabilecek argümanlara rağmen testlerin başarılı olmasına yol açar.
dtc

0

Çizgi

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);

aynı şeyi yapardı

when(someObject.doSomething(Matchers.any())).thenReturn(true);

Bu nedenle, saplama sırasında argumentCaptor.capture () yönteminin kullanılması katma değere sahip değildir. Matchers.any () kullanmak gerçekte ne olduğunu daha iyi gösterir ve dolayısıyla okunabilirlik için daha iyidir. ArgumentCaptor.capture () ile, hangi argümanların gerçekten eşleştiğini okuyamazsınız. Herhangi bir () kullanmak yerine, testinizi geliştirmek için daha fazla bilgiye (beklenen argümanın sınıfı) sahip olduğunuzda daha spesifik eşleştiriciler kullanabilirsiniz.

Ve başka bir sorun: Eğer saplama sırasında argumentCaptor.capture () kullanılırsa, doğrulamadan sonra kaç değer yakalanmasını beklediğiniz netleşmez. Saplama sırasında değil, doğrulama sırasında bir değer yakalamak istiyoruz çünkü o noktada henüz yakalanacak bir değer yok. Peki, sapanlar sırasında yakalama argümanları yöntem yakalamayı ne yapar? ya da bir şey yakalamıyor mu? Bu sorunun cevabı bende yok. Ben tanımsız davranış olarak görüyorum ve tanımsız davranış kullanmak istemiyorum.


0

Varsayımsal olarak, arama sizi bu soruya getirdiğinde, muhtemelen bunu istersiniz:

doReturn(someReturn).when(someObject).doSomething(argThat(argument -> argument.getName().equals("Bob")));

Neden? Çünkü benim gibi zamana değer veriyorsunuz ve uygulama yapmayacaksınız.equals sadece tek test senaryosu uğruna .

Ve testlerin% 99'u Mock'tan dönen null ile ayrılır ve makul bir tasarımda nullher ne pahasına olursa olsun geri dönmekten kaçınırsınız , OptionalKotlin'e girersiniz veya taşınırsınız. Bu verify, sık sık kullanılması gerekmediği ve ArgumentCaptors'ın yazmak için çok sıkıcı olduğu anlamına gelir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.