Mockito - szpiegowanie więcej niż jednej zależności

0

Czy jest możliwe szpiegować dwie wstrzyknięte zależności do tej samej, testowanej klasy?
Pytanie bierze się z pewnego problemu. Mam taką prostą klasę, z dwiema zależnościami:

@Service
@Singleton
@MessageReceiver
public class LinkHitCallbackEventHandler {
    public static final Logger logger = LogManager.getLogger();

    @Inject
    private CallbackInvocationBuilder callbackInvocationBuilder;

    @Inject
    private CallbackLogBuilder callbackLogBuilder;

    @MessageReceiver
    public void handle(@SubscribeTo LinkHitEvent event) {
        Entity<Form> entity = EntityFormFactory.createFromEvent(event);

        this.callbackLogBuilder.build(entity);

        Response response = this.callbackInvocationBuilder.post(entity);
    }
}

Testuję ją w taki sposób:

    @Test
    public void send_callback_after_event_is_published() {
        target("/testY")
                .property("jersey.config.client.followRedirects", false)
                .request()
                .header("User-Agent", UserAgentMother.allowedUserAagent())
                .get();

        verify(callbackInvocationBuilder).post(anyObject());
//        verify(callbackLogBuilder).build(anyObject());
    }

W ten sposób przechodzi pomyślnie, ponieważ najpierw wywołuję callbackLogBuilder.build(entity).

Jeśli zamienię wywołania miejscami i najpierw wywołam callbackInvocationBuilder.post(entity), test zakończy się niepowodzeniem.

Zarówno callbackLogBuilder, jak i callbackInvocationBuilder są zdeklarowane jako Mockito.spy(). Konfiguruję je w configure() z JerseyTest. Obie dokładnie w ten sam sposób.

3

Zasadnicze pytanie jest inne: po co chcesz coś takiego w ogole robić?

0

Przypadek jest upierdliwy. To test integracyjny, w którym wywołuję zadany endpoint POSTem. Nie interesuje mnie respons tego endpointa, a fakt, że w tle strzela callbackiem na inny endpoint. Te spy'ie mają sprawdzić czy request i response tego callbacka są poprawne.

Normalnie to powinno się zrobić testem akceptacyjnym z zewnątrz, ale chwilowo środowisko testowe na to nie pozwala. A dokonałem zmian w kodzie i jakoś musze je przetestować zanim zrobię deploy.

Tak czy siak problem się rozwiązał, wina leżała po stronie innych zależności, które były źle zmockowane i wywalały kod jeśli był w danej kolejności. Niemniej dzięki za odzew :D

3

To test integracyjny

Nie. Jeśli masz tam mockito to NIE JEST to test integracyjny.

Te spy'ie mają sprawdzić czy request i response tego callbacka są poprawne.

Więc powinieneś postawić w teście Embedded Http Server który oczekuje na zadany request i pozwala to zweryfikować. Możesz do tego uzyc jakiegoś WireMocka albo np. https://github.com/codewise-oss/canaveral/tree/master/canaveral-mocks/canaveral-downstream-http-mock
To co teraz zrobiłeś to półśrodek, bo wcale nie sprawdza czy to faktycznie zadziałało. Sprawdza tylko czy wywołano jakąś metodę na konkretnym obiekcie, nic więcej. Co jeśli ten obiekt nie działa? Albo jeśli logika się trochę zmieni i ten request jest wysyłany przez inna interakcje? Twój test nadal będzie zielony, mimo że funkcja nie działa.

1

Poczytaj o WireMocku, to będzie dla Ciebie skok w karierze :)

0

Używam Wiremocka w innym projekcie i tak jak napisałem tutaj chwilowo inaczej się nie da. Ten projekt ma swój projekt testów akceptacyjnych w Codeception, gdzie jest używany requestbin i również jak już pisalem brakuje mozliwosci technolgoicznych, zeby to tam zrobić.

Każdy głupi może napisać, że coś jego zdaniem nie jest lub nie powinno nazywać się testem integracyjnym ( mądry w sumie też ), troche trudniej jest podejść do tematu odwrotnie i podjąć rozważania jak taki test można nazwać, o czym chętnie bym podyskutował ;)

Ale jak chcesz mi kolego Shalom napisać, że test integracyjny z założenia nie ma prawa mieć mocków, to taka dyskusja chyba nie ma sensu :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1