Mockito - doReturn () ve when () arasındaki fark


198

Şu anda hizmet katmanı nesnelerimi Denetleyici yöntemlerimi test etmek istediğim bir Spring MVC uygulamasında alay etmek için Mockito kullanma sürecindeyim. Ancak, Mockito'nun özelliklerini okurken, yöntemlerin doReturn(...).when(...)eşdeğer olduğunu buldum when(...).thenReturn(...). Benim sorum şu: Aynı şeyi yapan iki metoda sahip olmanın anlamı nedir doReturn(...).when(...)ve ve arasındaki ince fark when(...).thenReturn(...)nedir?

Herhangi bir yardım mutluluk duyacağız.


1
Javadoc'un doReturn()yararlı olduğu birkaç durum vardır .
Sotirios Delimanolis

5
Bence en önemli fark doReturn (...). When (..). ThenReturn (..) tip güvenliği açısından çok daha iyi
user2511882

Yanıtlar:


229

Stubbing için iki sözdizimi kabaca eşdeğerdir. Ancak, olabilir , her zaman kullanmak doReturn/whenstubbing için; ancak durumlar vardır edemez kullanın when/thenReturn. Boşluk yöntemlerini saplama bunlardan biridir. Diğerleri Mockito casuslarıyla kullanımı ve aynı yöntemi bir kereden fazla stubbing içerir.

when/thenReturnSize veren, doReturn/whenvermeyen şeylerden biri , derlediğiniz zamanda döndürdüğünüz değerin tür denetlemesidir. Bununla birlikte, bunun neredeyse hiç bir değeri olmadığını düşünüyorum - eğer türü yanlış alırsanız, testinizi yürüttüğünüz anda öğreneceksiniz.

Sadece kullanmanızı şiddetle tavsiye ederim doReturn/when. Birinin iki sözdizimini öğrenmesinin bir anlamı yoktur.

Çok yakından ilgili bir soruya daha ayrıntılı bir cevap olan Forming Mockito "gramerleri" bölümündeki cevabımıza başvurabilirsiniz .


16
David'le aynı fikirde değilim. Sıklıkla kullanırken yanlış tipte döndüğüm durumlarla karşılaşıyorum doReturn/whenve önümüzdeki birkaç dakikayı neyin yanlış gittiğini anlamaya harcıyorum. Derleme türü türü denetimi ile son derece yararlı olur when/thenReturn.
Saket

11
Mockito'nun when/thenReturnbunun yerine kullanımı kullanmanızı önerdiğini unutmayın doReturn/when.
CodyEngel

2
@CodyEngel ve burada ve stackoverflow.com/q/11462697 adresindeki yanıtlarımda belirttiklerim dışında böyle bir öneri için hiçbir neden yok . Birkaç yıl önce, şu anda Mockito'nun baş geliştiricisi olan Brice Dutheil ile konuştum ve anımın en iyisine katılıyor. Burada bir yorum göndermesini isteyeceğim (bunu yapacağının garantisi yok).
Dawood ibn Kareem

18
Javadoc devletler doReturn/whenbir değiş tokuş vazifesi görür. Takım şu ya da bu şekilde tavsiye etmiyor ancak when/thenyaklaşımın daha sezgisel, daha okunabilir ve derleme zamanı kontrolü sunduğunu unutmayın, Mockito'yu popüler ve kullanımı kolay hale getiren yaklaşım, kod tabanı tarafından paylaşıldığında unutmayın takımınızda çeşitli yetenekler; yine de casuslar ve boşluk yöntemleri ile ilgili dezavantajları vardır.
Brice

5
Sadece kayıt için: doReturn()sahip büyük metot çağrıları kodlama YODA tarzı haline dezavantajı. Sonradan önce yazılı olan şey gelir. Çoğu insan soldan sağa okur; bu yüzden sürekli kafanızdaki dönüş mantığını tersine çevirmeyi hatırlamanız gerekir.
GhostCat

200

@SpySahte bir nesne (açıklamalı ) yerine sahte (açıklamalı) kullanırsanız her iki yaklaşım da farklı şekilde davranır @Mock:

  • when(...) thenReturn(...) belirtilen değer döndürülmeden hemen önce gerçek bir yöntem çağrısı yapar . Bu nedenle, çağrılan yöntem bir İstisna atarsa, onunla uğraşmanız / alay etmeniz gerekir. Tabii ki hala sonucunuzu alırsınız (tanımladığınız şey thenReturn(...))

  • doReturn(...) when(...) yöntemi hiç çağırmaz .

Misal:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

Ölçek:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");

37
Gerçek nesnelerin "sarıcı" olduğundan, bu davranış sadece casus nesneler için çalışır. Alaycı nesneler söz konusu olduğunda, ne zaman / thenReturn veya doReturn / when olduğu önemli değildir. Alay edilen nesneler asla gerçek yöntemler olarak adlandırmaz.
Rafael Orágio

Daha fazla bilgi verebilir misiniz, bu işlevi neden kullanmamız gerekiyor? Pratik kullanım durumu görmüyorum. Testin amacı, farklı kullanım durumlarında kodun doğruluğunu onaylamaktır. Yöntemin
calll

@Gleichmut Bu, doReturn'ün kullanımını / avantajını gösterdiğim varsayımsal bir senaryodur. Gerçek bir uygulamada, sadece bir istisna döndüren bir yöntem elbette bir anlam ifade etmiyor .. ama bazı durumlarda istisnalar atabilir yöntemleri (muhtemelen bu kadar ince değil) var ..
akcasoy

1
Sadece açıklığa kavuşturmak için: when (). ThenReturn () - yöntemi, gerçek yöntemi (bir casusun taklitleri için önemli değildir) yalnızca bir kez çağırır. Bu, sahte davranışı belirttiğiniz satırda gerçekleşir (( myClass.anotherMethodInClass () .thenRet ...). Bundan sonra gerçek yöntem bir daha çağrılmaz. Açıklamayı okurken bazı dekoratör mantığı bekleyip beklemediğinizi bilmek iyi olabilir. yukarıdaki.
Jonas

Bu bir avantaj gibi görünmüyor doReturn(), kütüphanenin kötüye kullanılması gibi görünüyor. Saf alay yerine casusluk yapmak gerçek çağrılardan faydalanmaktır. Ayrıca Spies'i şu şekilde kullanmaya karşı uyarıyorlar: github.com/mockito/mockito/wiki/Using-Spies-(and-Fakes) (ve sınıfı genişletmeyi ve bunun yerine yöntemi geçersiz kılmayı öneriyorlar)
Matthew

13

Mockito javadoc , Mockito.when (Object) öğesini kullanamadığınızda nadir durumlarda Neden doReturn () doReturn()yerine kullanımın olduğunu söylüyor gibi görünüyor when().

Mockito.when (Nesne) 'nin her zaman saplama için önerildiğine dikkat edin, çünkü argüman tipi güvenli ve daha okunabilirdir (özellikle ardışık çağrıları saklarken).

DoReturn () işlevinin kullanışlı olduğu nadir durumlar şunlardır:

1. Bir casus üzerinde gerçek nesneleri casusluk yaparken ve gerçek yöntemleri çağırırken yan etkiler getirir

List list = new LinkedList(); List spy = spy(list);

// İmkansız: gerçek yönteme spy.get (0) adı verilir IndexOutOfBoundsException (liste henüz boş)

when(spy.get(0)).thenReturn("foo");

// Saplama için doReturn () yöntemini kullanmanız gerekir: doReturn("foo").when(spy).get(0);

2. Önceki istisna saplamalarını geçersiz kılma:

when(mock.foo()).thenThrow(new RuntimeException());

// İmkansız: istisna-stubbed foo () yöntemi çağrılır, böylece RuntimeException oluşturulur. when(mock.foo()).thenReturn("bar");

// Saplama için doReturn () yöntemini kullanmanız gerekir:

doReturn("bar").when(mock).foo(); Yukarıdaki senaryolar Mockito'nun zarif sözdiziminin bir dengesini gösterir. Ancak senaryoların çok nadir olduğunu unutmayın. Casusluk sporadik olmalı ve istisna-stubbing'i geçersiz kılmak çok nadirdir. Genel olarak, stubbing'in geçersiz kılınmasının çok fazla stubbinge işaret eden potansiyel bir kod kokusu olduğunu belirtmiyoruz.


7

Bu cevaba devam ederseniz, yönteminizin örneğin ilk kez çağrıldığında, ikinci kez vb. Çağrıldığında farklı değerler döndürmesini istiyorsanız başka bir fark daha vardır;

PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));

Bu nedenle, yöntem aynı test durumunda çağrıldığında false döndürür ve sonra tekrar false ve son olarak true döndürür.


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.