Mockito tartışmayı dikkate almadan bir yöntemi saplayabilir mi?


302

Mockito kullanarak bazı eski kodları test etmeye çalışıyorum.

FooDaoÜretimde kullanılan a saplamasını aşağıdaki gibi yapmak istiyorum:

foo = fooDao.getBar(new Bazoo());

Yazabilirim:

when(fooDao.getBar(new Bazoo())).thenReturn(myFoo);

Ama asıl sorun, getBar()yöntemi asla Bazoosapladığım aynı nesne ile çağrılmamasıdır . (O newoperatörü lanetleyin !)

Metodu myFoo, argümandan bağımsız olarak geri dönecek şekilde saplayabilirsem çok isterdim . Başarısız olursa, diğer geçici çözüm önerilerini dinleyeceğim, ancak makul test kapsamı olana kadar üretim kodunu değiştirmekten gerçekten kaçınmak istiyorum.

Yanıtlar:


456
when(
  fooDao.getBar(
    any(Bazoo.class)
  )
).thenReturn(myFoo);

veya (önlemek için null):

when(
  fooDao.getBar(
    (Bazoo)notNull()
  )
).thenReturn(myFoo);

Eşleştiricileri içe aktarmayı unutmayın (diğerleri de mevcuttur):

Mockito 2.1.0 ve daha yeni sürümler için:

import static org.mockito.ArgumentMatchers.*;

Eski sürümler için:

import static org.mockito.Matchers.*;

2
Cevabı 'cevap dondurmayı kabul et' ifadesinin sonundan önce geldiğinde seviyorum.
Eric Wilson

10
Bir var notNull(Bazoo.class)gibi any(Bazoo.class)(belki de bu cevabın anda var olmayan)
Dandre Allison

2
iki olası argümandan birine sahip olabileceğim Bazooya Cazooda her ikisinin de alt sınıfı olan biraz özel bir durumum vardı Azoo. Bazoogeri dönmek için gerekli foo, ama geri dönmek için Cazoogerekli bar. bu durumda önerilen Matchers.any()çözüm işe yaramaz, ancak Matchers.isA()mükemmel çalışır.
Tanvir

3
org.mockito.Matchersartık kullanımdan kaldırıldı - org.mockito.ArgumentMatchersbunun yerine kullanın, yani import static org.mockito.ArgumentMatchers.*( dokümanlara bakın )
DontDivideByZero

when(myFoo.knowsWhatsUp()).thenReturn(myMoney);
6rchid

18

Bunun gibi kullanın:

when(
  fooDao.getBar(
    Matchers.<Bazoo>any()
  )
).thenReturn(myFoo);

İçe aktarmanız gerekmeden önce Mockito.Matchers


1
Bu karmaşık!
DrB

15

http://site.mockito.org/mockito/docs/1.10.19/org/mockito/Matchers.html

anyObject() ihtiyaçlarınızı karşılamalıdır.

Ayrıca, her zaman uygulamayı hashCode()ve sınıf equals()için düşünebilirsiniz Bazoo. Bu, kod örneğinizin istediğiniz şekilde çalışmasını sağlayacaktır.


İkinci öneriyi kabul ettim, ancak hala teknik olmayan nedenlerle bunu yapmamayı tercih ediyorum.
Eric Wilson

1
Matchers sınıfı kullanımdan kaldırıldı (bkz. Dokümanlar - "Bu sınıf muhtemelen 3.0 sürümünde kaldırılacak" )
Johannes Rabauer

1

Başka bir seçenek de eski moda equalsyöntemine güvenmektir . whenSahte equalsargüman test edilen kodda argüman sürece , o zaman Mockito sahte ile eşleşecektir.

İşte bir örnek.

public class MyPojo {

    public MyPojo( String someField ) {
        this.someField = someField;
    }

    private String someField;

    @Override
    public boolean equals( Object o ) {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;
        MyPojo myPojo = ( MyPojo ) o;
        return someField.equals( myPojo.someField );
    }

}

sonra, değerinin ne someFieldolacağını bildiğinizi varsayarsak , bu şekilde alay edebilirsiniz.

when(fooDao.getBar(new MyPojo(expectedSomeField))).thenReturn(myFoo);

Artıları: Bu anymaççılardan daha açık . Bir kod gözden geçiren anyolarak, uygun geliştirici nesneyi oluşturmak için kendi kodun mantığı üzerine bakış gibi genç geliştiriciler yazma kodu için bir göz açık tutmak .

con: Bazen nesneye iletilen alan rastgele bir kimliktir. Bu durumda, sahte kodunuzda beklenen bağımsız değişken nesnesini kolayca oluşturamazsınız.

Bir başka olası yaklaşım, Mockito'nun Answeryöntemle kullanılabilecek nesnesini kullanmaktır when. Answergerçek çağrıyı kesip giriş argümanını incelemenizi ve bir sahte nesne döndürmenizi sağlar. Aşağıdaki örnekte any, taklit edilen yönteme yönelik herhangi bir isteği yakalamak için kullanıyorum . Ama sonra Answerlambda'da Bazo argümanını daha da inceleyebilirim ... belki ona doğru bir ID'nin geçtiğini doğrulamak için. Bunu anytek başına tercih ederim, böylece en azından argüman üzerinde bir inceleme yapılır.

    Bar mockBar = //generate mock Bar.

    when(fooDao.getBar(any(Bazo.class))
    .thenAnswer(  ( InvocationOnMock invocationOnMock) -> {
        Bazo actualBazo = invocationOnMock.getArgument( 0 );

        //inspect the actualBazo here and thrw exception if it does not meet your testing requirements.
        return mockBar;
    } );

Sonuç olarak, güvenmeyi seviyorum equals(beklenen argümanın ve gerçek argümanın birbirine eşit olması gerektiği yerde) ve eşitler mümkün değilse (asıl argümanın durumunu tahmin edemediği için), başvururum için Answerbağımsız değişkeni incelemek için.

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.