используя @InjectMocks за пределами @Before

, если вы используете идеал типа eclipse, он расскажет вам, какие методы вам нужно реализовать для интерфейсов:

import java.util.*;
class Card {}
class Deck implements Cloneable,Iterable<Card>,Comparator<Card> {
    public Deck() {}
    @Override public int compare(Card arg0,Card arg1) {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override public Iterator<Card> iterator() {
        // TODO Auto-generated method stub
        return null;
    }
    private ArrayList<Card> cards;
}

итератор прост, так как в списке массивов есть один. ищите примеры сопоставимых. вам придется как-то инициализировать колоду. Я поставил статический конечный массив в классе моей карты, который содержал все карты. вы можете сделать все из этого массива, используя массивы в виде списка.

2
задан ulquiorra 5 March 2019 в 16:20
поделиться

1 ответ

Это работает как задумано. Однако вы можете настроить макеты вручную и вставить их в конструктор ConnectionManagementControllerImplTest (перед вызовом setTestClass(...)):

public ConnectionManagementControllerImplTest() {
    super();

    connectionManagementBusinessServiceMocked = Mockito.mock(ConnectionManagementBusinessService.class);

    connectionManagementControllerMocked = new ConnectionManagementControllerImpl();
    connectionManagementControllerMocked.setConnectionManagementBusinessService(connectionManagementBusinessServiceMocked);

    setTestClass(ConnectionManagementControllerImpl.class, connectionManagementControllerMocked);
}

Не забудьте удалить аннотации @Mock и @InjectMocks. Кстати, вы даже можете удалить @RunWith(MockitoJUnitRunner.class) в этом случае.

ОБНОВЛЕНИЕ: И конструктор класса теста, и метод «init» с аннотацией @Before выполняются для каждого теста. Разница в том, что аннотации Mockito обрабатываются между вызовами методов конструктора и @Before.

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

  1. Создать метод «init» (с примечанием @Before) внутри ConnectionManagementControllerImplTest и переместить setTestClass() ] в конструктор (в этом конкретном случае вы также можете удалить весь конструктор, поскольку он будет содержать только super() вызов).
  2. Добавьте super.init() после строки setTestClass() (в противном случае метод "init" в родительском классе будет игнорироваться JUnit).
  3. (Необязательно) вы также можете удалить аннотацию @Before из метода «init» в родительском классе, если ваши тесты написаны таким же образом.

Пример кода, измененного таким образом:

public abstract class AbstractBaseTest<C> {

    public MockMvc mockMvc;

    private Class<C> clazz;

    private Object inject;

    protected abstract String getURL();

    protected final void setTestClass(final Class<C> classToSet, final Object injectToSet) {
        clazz = Preconditions.checkNotNull(classToSet);
        inject = Preconditions.checkNotNull(injectToSet);
    }

    @Before //this annotation can be removed
    public void init() throws Exception {
        MockitoAnnotations.initMocks(clazz); //this line also can be removed because MockitoJUnitRunner does it for you
        mockMvc = MockMvcBuilders.standaloneSetup(inject).build();
    }

    protected MockHttpServletResponse getResponse(MediaType produces) throws Exception {
        MockHttpServletResponse response = mockMvc.perform(
                get(getURL()).
                        accept(produces)).
                andReturn().
                getResponse();
        return response;
    }

    protected MockHttpServletResponse postResponse(String content , MediaType consumes , MediaType produces) throws Exception {
        MockHttpServletResponse response = mockMvc.perform(
                post(getURL()).
                        content(content).
                        contentType(consumes).
                        accept(produces)).
                andReturn().
                getResponse();
        return response;
    }
}
@RunWith(MockitoJUnitRunner.class)
public class ConnectionManagementControllerImplTest extends AbstractBaseTest<ConnectionManagementControllerImpl> {

    @Mock
    private ConnectionManagementBusinessService connectionManagementBusinessServiceMocked;

    @InjectMocks
    private ConnectionManagementControllerImpl connectionManagementControllerMocked;

    //constructor can be removed
    public ConnectionManagementControllerImplTest() {
        super();
    }

    @Before
    public void init() throws Exception {
        setTestClass(ConnectionManagementControllerImpl.class, connectionManagementControllerMocked);
        super.init();
    }

    @Test
    public void countConnectionsByInterval() throws Exception {

        // given
        given(connectionManagementBusinessServiceMocked.countConnectionsByInterval(Mockito.anyString()))
                .willReturn(new ArrayList<ConnectionsCountDto>());

        // when
        MockHttpServletResponse response = postResponse("day", MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON_UTF8);

        // then
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
    }

    @Override
    protected String getURL() {
        return "/management/countConnectionsByInterval";
    }
}

P.S. Я бы предпочел первый подход, но если вы не хотите иметь установщик для ConnectionManagementBusinessService, вы можете выбрать второй. Я проверил их обоих, и результат был одинаковым.

0
ответ дан amseager 5 March 2019 в 16:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: