Как издеваться над строителем с помощью мокито - PullRequest
26 голосов
/ 14 декабря 2011

У меня есть строитель:

class Builder{
     private String name;
     private String address;
     public Builder setName(String name){
         this.name = name;
         return this;
    }
     public Builder setAddress(String address){
         this.address = address;
         return this;
    }

}

Насмешка над строителем в mockito даст мне нулевое значение для каждого метода. Таким образом, существует ли простой способ заставить конструктор возвращать себя при каждом вызове функции, без насмешек над каждой функцией, используя when().thenReturn.

Ответы [ 3 ]

40 голосов
/ 16 декабря 2011

Проблема с использованием RETURN_DEEP_STUBS заключается в том, что вы будете получать разные макеты при каждом вызове метода.Я думаю из вашего вопроса, что вы хотите использовать ответ по умолчанию, который фактически возвращает макет, для которого он был вызван, для каждого метода, который имеет правильный тип возвращаемого значения.Это может выглядеть примерно так:Обратите внимание, что я не проверял это, поэтому он может содержать опечатки, но я надеюсь, что намерение ясно в любом случае.

import static org.mockito.Mockito.RETURNS_DEFAULTS;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class SelfReturningAnswer implements Answer<Object>{

    public Object answer(InvocationOnMock invocation) throws Throwable {
        Object mock = invocation.getMock();
        if( invocation.getMethod().getReturnType().isInstance( mock )){
            return mock;
        }
        else{
            return RETURNS_DEFAULTS.answer(invocation);
        }
    }
}

Затем, когда вы создаете макет, укажите это как ответ по умолчанию,Это заставит ваш макет возвращать себя из каждого метода, который он может;но он будет вести себя как обычный макет, когда вы вызываете метод, тип возвращаемого значения которого неправильный для макета.

Создайте свой макет следующим образом

Builder mockBuilder = mock( Builder.class, new SelfReturningAnswer());

или создайте константу для этого класса инапишите что-нибудь вроде

@Mock( answer = SELF_RETURNING ) private Builder mockBuilder;

Надеюсь, это поможет.

18 голосов
/ 24 марта 2016

Начиная с Mockito 2.0 (бета), существует новый ответ по умолчанию для RETURNS_SELF, который ведет себя почти идентично ответу Дэвида Уоллеса .Пример из документов Mockito:

@Test
public void use_full_builder_with_terminating_method() {
    HttpBuilder builder = mock(HttpBuilder.class, RETURNS_SELF);
    HttpRequesterWithHeaders requester = new HttpRequesterWithHeaders(builder);
    String response = "StatusCode: 200";

    when(builder.request()).thenReturn(response);

    assertThat(requester.request("URI")).isEqualTo(response);
}

Обратите внимание, что он появляется как в классе Mockito, так и в перечислении Answers, поэтому он также совместим с синтаксисом @Mock(answer = RETURNS_SELF).

10 голосов
/ 14 декабря 2011

Вы можете использовать RETURN_DEEP_STUBS для насмешки связующего API.

Если вы знаете точный порядок вызова вашего строителя, вот пример того, как вы будете его использовать:

Builder b = Mockito.mock(Builder.class, RETURNS_DEEP_STUBS);
when(b.setName("a name").setAddress("an address")).thenReturn(b);
assert b.setName("a name").setAddress("an address") == b; // this passes

К сожалению, это не даст вам общий способ насмешки над "всеми различными методами построения", чтобы они всегда возвращали это, смотрите другой ответ: вам это нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...