Soru Mockito ile geri aramalar


Biraz kodum var

service.doAction(request, Callback<Response> callback);

Mockito'yu kullanarak geri arama nesnesini nasıl kullanabilirim ve callback.reply (x) çağrısı


43
2017-11-28 23:54


Menşei




Cevaplar:


Sen kurmak istiyorsun Answer Bunu yapan nesne. Mockito belgelerine bir göz atın. https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#answer_stubs

Gibi bir şey yazabilirsin

when(mockService.doAction(any(Request.class), any(Callback.class))).thenAnswer(
    new Answer<Object>() {
        Object answer(InvocationOnMock invocation) {
            ((Callback<Response>) invocation.getArguments()[1]).reply(x);
            return null;
        }
});

(yerine x her ne olursa olsun, elbette)


57
2017-11-28 23:56



Btw, fonksiyon geçersiz olduğunda, bir doAnswer (...) yapmak için (mockedObject) .method (herhangi bir (Geri arama []. Sınıf)); açıklandığı gibi stackoverflow.com/questions/3581754/... - Thomas
İşte benzer bir şey için başka bir bağlantı testing.googleblog.com/2014/03/... - Matt D


Kullanarak düşünün ArgumentCaptor, her durumda "geri arama nesnesini [bing] almak" için daha yakın bir eşleşme olan.

/**
 * Captor for Response callbacks. Populated by MockitoAnnotations.initMocks().
 * You can also use ArgumentCaptor.forClass(Callback.class) but you'd have to
 * cast it due to the type parameter.
 */
@Captor ArgumentCaptor<Callback<Response>> callbackCaptor;

@Test public void testDoAction() {
  // Cause service.doAction to be called

  // Now call callback. ArgumentCaptor.capture() works like a matcher.
  verify(service).doAction(eq(request), callbackCaptor.capture());

  assertTrue(/* some assertion about the state before the callback is called */);

  // Once you're satisfied, trigger the reply on callbackCaptor.getValue().
  callbackCaptor.getValue().reply(x);

  assertTrue(/* some assertion about the state after the callback is called */);
}

Bir süre Answer geri dönüşün hemen geri dönmesi gerektiğinde (okuma: eşzamanlı olarak) iyi bir fikirdir, aynı zamanda anonim bir iç sınıf yaratmanın ek yükünü ve öğelerin kasıtsız olarak dökülmesini sağlar. invocation.getArguments()[n] İstediğiniz veri türüne. Ayrıca, Sistemin geri arama durumu ile ilgili olarak, yanıtın BÜTÜNLEŞMEDEN herhangi bir iddiada bulunmanızı gerektirir; bu, Yanıtınızın boyut ve kapsamda büyüyebileceği anlamına gelir.

Bunun yerine, geri çağrınızı eşzamansız olarak ele alın: Bir ArgumentCaptor kullanarak hizmetinize iletilen Geri Arama nesnesini yakalayın. Şimdi tüm onaylamalarınızı test yöntemi seviyesinde yapabilirsiniz ve reply seçtiğinizde. Bu, özellikle birden fazla eşzamanlı geri arama işleminden sorumluysa, özellikle, geri aramaların geri döndüğü sıra üzerinde daha fazla kontrole sahip olmanız nedeniyle, bu özellikle kullanılır.


37
2017-11-29 04:04



Ancak, geri arama yönteminin test tarafından dolaylı olarak çağrılması durumunda bunu yapabilirsiniz (başka bir deyişle, test kodunda tetiklenen ancak test kodunda olmayan bir şey tarafından çağrılır)? - Thomas
Genel olarak, bir ünite testinde geri arama ile çalışıyorsanız, sisteminizin test edilmek üzere bir arayüzde (alay edebileceksiniz) geçiyorsunuz ya da bir bağımlılığın aldığı Bir geri arama (bu nedenle, yukarıdaki gibi geri arama kendiniz aramak zorunda). Yakalanan geri arama arabirimini aramak için başka bir sınıfa vermemiz normal değil ama yapamayacağın bir sebep yok. Demek istediğin bu muydu? - Jeff Bowman
Kullanarak güvenlik sorununu önleyebilirsiniz invocation.getArgumentAt(1, Callback.class).reply(); - Steve
@Steve Sorunu engellemez, bu sadece dökümanı bir yöntem çağrısında gizler. Hala çalışma zamanında iddiasındasınız. arguments[1] Derleyici, kendisini garanti edemeyeceğinden daha fazla olan bir Geri Çağırma değil, bir Geri Çağırmadır. Büyük bir anlaşma değil, ama bu bir fark. - Jeff Bowman


when(service.doAction(any(Request.class), any(Callback.class))).thenAnswer(
    new Answer() {
    Object answer(InvocationOnMock invocation) {
        Callback<Response> callback =
                     (Callback<Response>) invocation.getArguments()[1];
        callback.reply(/*response*/);
    }
});

2
2017-11-29 00:00





Eğer şöyle bir yöntem varsa: -

public void registerListener(final IListener listener) {
    container.registerListener(new IListener() {
        @Override
        public void beforeCompletion() {
        }

        @Override
        public void afterCompletion(boolean succeeded) {
            listener.afterCompletion(succeeded);
        }
    });
}

Daha sonra aşağıdaki yöntemi kolayca takip edebilirsiniz: -

@Mock private IListener listener;

@Test
public void test_registerListener() {
    target.registerListener(listener);

    ArgumentCaptor<IListener> listenerCaptor =
            ArgumentCaptor.forClass(IListener.class);

    verify(container).registerListener(listenerCaptor.capture());

    listenerCaptor.getValue().afterCompletion(true);

    verify(listener).afterCompletion(true);
}

Bu çözümün çözülmesinde çok zaman harcadığım için bunun birilerine yardımcı olabileceğini umuyorum


0
2017-08-06 18:11