Cannot run Unit Tests against REST layer

被刻印的时光 ゝ 提交于 2020-01-14 03:04:07

问题


I cannot unit test the web layer using jhipster (according to spring gs guides):

@RunWith(SpringRunner.class)
@WebMvcTest
public class FlightControllerTest {


    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private FlightService flightService;

    @Test
    public void testCreate() throws Exception {

        FlightDto expected = new FlightDto();
        ReflectionTestUtils.setField(expected, "id", 1L);

        when(flightService.createFlight(any(FlightDto.class))).thenReturn(expected);

        FlightDto flightDto = new FlightDto();
        flightDto.setNumber("CAI-123400");

        this.mockMvc.perform(post("/api/flight")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(flightDto)))
                .andDo(print())
                .andExpect(status().isCreated())
                .andExpect(header().string("Location", endsWith("/api/flight/1")));
    }

}

The above Unit test success in case of green-field spring boot project, but fails in case of green-field spring boot-based jhipster project:

When run Unit Test in jhispter project (springboot-with-jhipster) from FlightResource I got:

java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test

    at org.springframework.util.Assert.state(Assert.java:70)
    at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.getOrFindConfigurationClasses(SpringBootTestContextBootstrapper.java:202)
    at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.processMergedContextConfiguration(SpringBootTestContextBootstrapper.java:137)
    at org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper.processMergedContextConfiguration(WebMvcTestContextBootstrapper.java:35)
    at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:409)
    at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildDefaultMergedContextConfiguration(AbstractTestContextBootstrapper.java:323)
    at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:277)
    at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildTestContext(AbstractTestContextBootstrapper.java:112)
    at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.buildTestContext(SpringBootTestContextBootstrapper.java:82)
    at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:120)
    at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:105)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTestContextManager(SpringJUnit4ClassRunner.java:152)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:143)
    at org.springframework.test.context.junit4.SpringRunner.<init>(SpringRunner.java:49)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:49)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

回答1:


I can run the test with this code:

@RunWith(SpringRunner.class)

//@WebMvcTest remove @WebMvcTest
//add SpringBootTest
@SpringBootTest(classes = JhUnittestRestApp.class)
public class FlightResourceTest {

    //@Autowired remove anotation
    private MockMvc mockMvc;

    @MockBean
    private FlightService flightService;

    @Autowired
    private MappingJackson2HttpMessageConverter jacksonMessageConverter;

    @Autowired
    private PageableHandlerMethodArgumentResolver pageableArgumentResolver;

    @Autowired
    private ExceptionTranslator exceptionTranslator;

    @Before
    public void setup() {
        //initialize the bean
        MockitoAnnotations.initMocks(this);
        final FlightResource flightResource = new FlightResource(flightService);
        this.mockMvc = MockMvcBuilders.standaloneSetup(flightResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setConversionService(createFormattingConversionService())
            .setMessageConverters(jacksonMessageConverter).build();
    }

    @Test
    public void testCreate() throws Exception {

        FlightDTO expected = new FlightDTO();
        ReflectionTestUtils.setField(expected, "id", 1L);

        when(flightService.save(any(FlightDTO.class))).thenReturn(expected);

        FlightDTO flightDto = new FlightDTO();
        flightDto.setNumber("CAI-123400");
        //update the url to /api/flights so that the test can pass 
        this.mockMvc.perform(post("/api/flights")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(flightDto)))
            .andDo(print())
            .andExpect(status().isCreated())
            .andExpect(header().string("Location", endsWith("/api/flights/1")));
    }

}

Your FlightControllerTest is working in your springboot-no-jhipster project because the main class of the project is annotated with @SpringBoot According to the documentation of @SpringBoot

The @SpringBootApplication annotation is equivalent to using:
@Configuration, @EnableAutoConfiguration and @ComponentScan with their default attributes

Since JHipster needs some more configuration than just the default, JHipster is not using @SpringBootApplication as you can see in your project. This is perfectly OK and works without problems.

On the other hand the error message of your test is saying that it can't detect @SpringBootConfiguration. There are other annotation e.g. @ContextConfiguration or @SpringBootTest that are rocomandet to use for the test. Actually there are some inconsistencies on which annotation in main config class fits with the test annotations see here or here.



来源:https://stackoverflow.com/questions/48976046/cannot-run-unit-tests-against-rest-layer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!