Ich habe Schwierigkeiten, Mockito und MockMvc zusammenzuarbeiten, wenn ich das webAppContextSetup zusammen benutze. Ich bin neugierig, ob es daran liegt, dass ich die beiden auf eine Weise mische, die sie nie beabsichtigt haben.Soll Mockito mit MockMvcs webAppContextSetup in Spring 4 verwendet werden?
Hier ist der Test, den ich laufen werde:
package com.zgardner.springBootIntro.controller;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static java.lang.Math.toIntExact;
import static org.hamcrest.Matchers.is;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import com.zgardner.springBootIntro.Application;
import com.zgardner.springBootIntro.service.PersonService;
import com.zgardner.springBootIntro.model.PersonModel;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class PersonControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private DefaultListableBeanFactory beanFactory;
@Mock
private PersonService personService;
@InjectMocks
private PersonController personController;
@Before
public void setup() {
initMocks(this);
// beanFactory.destroySingleton("personController");
// beanFactory.registerSingleton("personController", personController);
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void getPersonById() throws Exception {
Long id = 999L;
String name = "Person name";
when(personService.findById(id)).thenReturn(new PersonModel(id, name));
mockMvc.perform(get("/person/getPersonById/" + id))
.andDo(print())
.andExpect(jsonPath("$.id", is(toIntExact(id))))
.andExpect(jsonPath("$.name", is(name)));
}
}
Ich hatte erwartet, dass, wenn mockMvc die mock dieser HTTP-Aufruf ausgeführt, würde es die PersonController verwende ich in meinem definiert Prüfung. Aber wenn ich durch Debugging, es verwendet den PersonController, die von der SpringJunit4ClassRunner beim Teststart erstellt wurde.
fand ich zwei Möglichkeiten, dies zu Arbeit zu bekommen:
- die BeanFactory injizieren, die alte personController Singleton entfernen, und meine eigenen hinzufügen. Das ist hässlich und ich bin kein Fan.
- Verbinden Sie alles mit dem StandaloneSetup anstelle von webAppContextSetup. Ich kann dies stattdessen tun, da ich die Bohnenfabrik nicht anfassen muss.
Hier sind einige andere Artikel, die ich gefunden habe, die etwas über das Thema berühren:
- Spring Tutorial - Building REST Services Dies ist nur in den repos autowires die Daten zu löschen, bevor der Integrationstest stattfindet.
- Use Spring MVC Test framework and Mockito to test controllers Dies nutzt Mockito zusammen mit webAppContextSetup, aber dies ist im Frühjahr 3. (Ich bin mit Spring Boot)
- Unable to mock Service class in Spring MVC Controller tests Dies verwendet die standaloneSetup, die zu Arbeit in meinem Fall tut.
Gedanken?