Mockito kullanılarak belirli bir yöntemin çağrılmadığını nasıl doğrularım?


625

Nasıl bir yöntem olduğunu doğrulamak için değil , bir nesnenin bağımlılık çağırdı?

Örneğin:

public interface Dependency {
    void someMethod();
}

public class Foo {
    public bar(final Dependency d) {
        ...
    }
}

Foo testi ile:

public class FooTest {
    @Test
    public void dependencyIsNotCalled() {
        final Foo foo = new Foo(...);
        final Dependency dependency = mock(Dependency.class);
        foo.bar(dependency);
        **// verify here that someMethod was not called??**
    }
}

Yanıtlar:


1087

Daha da anlamlı:

import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

// ...

verify(dependency, never()).someMethod();

Bu özelliğin belgeleri şurada mevcuttur: §4 "Tam çağrı sayısını / en azından x / asla doğrulama" ve neverjavadoc burada .


144
Kullanmak neveren iyi ve en spesifik yoldur, ancak sahte bir nesnenin tamamını kontrol etmeniz gerekiyorsa, verifyZeroInteractions(mockObject)veya seçeneğini de göz önünde bulundurun verifyNoMoreInteractions(mockObject).
Jeff Bowman

someMethod özelse ne yapmalı?
Sumit Kumar Saha

1
Sonra ilk etapta alay edemezsiniz (Mockito ile);) PowerMock buna izin verir, ancak kurmak daha karmaşıktır. Veya kodun sahibi sizseniz, paketin görünürlüğünü rahatlatırsınız.
Brice

2
3.0.1'den verifyZeroInteractionsberi kullanımdan kaldırıldı. verifyNoInteractions önerilen bir alternatiftir. Bu yorumun yapıldığı tarihte Mockito versiyonu 3.3.3
VKB

108

Mockito.verifyyöntemdeki ikinci bağımsız değişkeni aşağıdaki gibi kullanın :

verify(dependency, Mockito.times(0)).someMethod()


11
public static VerificationMode never () {dönüş süreleri (0); }
gbero

3
never()önemli ölçüde daha okunabilir değildir times(0). Ancak varlığı, neverbilişsel yükü artırır ve mockito sistemini nasıl kullanıldığını anlamayı ve hatırlamayı zorlaştırır. Yani gerçekten mockito neverkendi zihinsel maliyet değmez, onların API dahil olmamalıdır .
BT

Soru: Bu form someMethod0 kez çağrıldığını mı, yoksa yalnızca someMethodsıfır argümanıyla çağrılmadığını mı doğrular ?
BT

@BT - someMethodSıfır argümanları ile sıfır kez denir doğrulanmadığını hayal ediyorum - doğrulanmadı.
beluchin

18

Takip edilecek daha genel bir model olarak @After, testte bir blok kullanma eğilimindeyim :

@After
public void after() {
    verifyNoMoreInteractions(<your mock1>, <your mock2>...);
}

Daha sonra test sadece neyin çağrılması gerektiğini doğrulamakta serbesttir .

Ayrıca, sık sık “etkileşim yok” u kontrol etmeyi unuttuğumu, daha sonra olması gerekmeyen şeylerin çağrıldığını keşfetmeyi unuttum.

Bu yüzden, bu modeli özel olarak doğrulanmamış tüm beklenmedik çağrıları yakalamak için yararlı buluyorum.


9
Mockito dokümantasyonu, bu örüntünün kötüye kullanılmaması gerektiğini belirtiyor - "Bir uyarı: Çok sayıda klasik, bekle-çalıştır-doğrula alaycılığı yapan bazı kullanıcılar, her test yönteminde bile verifyNoMoreInteractions () yöntemini sıklıkla kullanma eğilimindedir. () her test yönteminde kullanılması önerilmez. verifyNoMoreInteractions (), etkileşim testi araç setinden kullanışlı bir iddiadır. Yalnızca alakalı olduğunda kullanın. Buraya
Chadi

2
"Sadece alakalı olduğunda kullanın". Her zaman alakalı olduğunu hissediyorum. Bu kalıbı kötüye kullanım olarak görmüyorum: dediğim gibi, "olması gerekmeyen şeyler deniyordu" buluyor. Bana göre, bu çok önemli bir doğrulama parçası: eğer bir şey kullanılmaması gereken bir depo çağırıyorsa, bunu bilmek istiyorum! Bunu kullanmadan doğrulamanın başka bir yolu yoksa verifyNoMoreInteractions? Buradaki diğer cevaplar, bu kontrolleri listelemeyi açıkça hatırlayan test yazarına dayanıyor: bu, kitabımda çok hata eğilimli.
David Lavender

2
Ben bu yorumu gördüm, ama aynı zamanda muhakeme zorlayıcı değildi gibi hissettim. Bunun neden önerilmediğini daha fazla okumak isterim.
tobinibot

2
@tobinibot Çünkü birim testi fikri bir Sözleşmeyi doğrulamaktır. Çoğu sözleşme tipik olarak başka bir yöntemin kaç kez çağrıldığını içermez, bunun yerine bilinen parametrelerin iletilmesinin bilinen bir yanıta yol açmasıdır. Daha fazla etkileşim kullanmadan, temel olarak uygulamayı satır satır doğrularsınız, bu da yeniden düzenleme ve uygulamayı sıkıcı hale getirir. Birim testin konusu bu değil.
Andrew T Finnell

8

Her şeyden önce: her zaman mockito static'i içe aktarmalısınız, bu şekilde kod çok daha okunabilir (ve sezgisel) olacaktır:

import static org.mockito.Mockito.*;

Aslında bunu başarmanın birçok yolu vardır, ancak (tartışmalı olarak)

verify(yourMock, times(0)).someMethod();

diğer Testlerde, bunun gibi belirli bir sayıda yürütmeyi iddia etmek için kullandığınızda:

verify(yourMock, times(5)).someMethod();

Alternatifler:

verify(yourMock, never()).someMethod();

Alternatif olarak - gerçekten alaycı bir Nesnenin gerçekten çağrılmadığından emin olmak istediğinizde şunları kullanabilirsiniz:

verifyZeroInteractions(yourMock)

7

Hem verifyNoMoreInteractions()ve verifyZeroInteractions()yöntemi dahili olarak aşağıdakilerle aynı uygulamaya sahiptir:

public static transient void verifyNoMoreInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

public static transient void verifyZeroInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

bu nedenle, sahte nesneler kullanılarak hiçbir yöntemin çağrılmadığını kontrol etmek için bunlardan herhangi birini sahte nesne veya sahte nesne dizisi üzerinde kullanabiliriz.

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.