当前位置: 首页 > 知识库问答 >
问题:

为什么我不能将控制器实例自动转换到这个Spring Boot应用程序的JUnit类中?找不到@SpringBootConfiguration

公西修文
2023-03-14
@RestController
@RequestMapping("/PlaceSearcher")
public class PlaceSearcherController {

    private static final Logger log = LoggerFactory.getLogger(PlaceSearcherController.class);


    @Autowired
    private MainSearchServices mainSearchServices;

    @RequestMapping(value = "hello")
    public String hello() {
        return "Hello World";
    }

    @RequestMapping(value = "",
            method = RequestMethod.GET)
    public ResponseEntity<String> home() {
        List<AccomodationDTO> accomodationDTOs = new ArrayList<>();

        return ResponseEntity.ok("c è figa");
    }

    @RequestMapping(value = "getBestListHotel",
            method = RequestMethod.POST,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<AccomodationDTO>> getHolteListFromPlace(@Valid @RequestBody MainSearchListHotelVO searchObject) {
        List<AccomodationDTO> accomodationDTOs = new ArrayList<>();

        log.debug("search vo in input: " + searchObject);
        try {
            accomodationDTOs = mainSearchServices.getBestHotelListFromPlace(searchObject);
        } catch (Exception e) {
            log.error("Exception: ", e);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
        }

        if (accomodationDTOs.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);
        }

        return ResponseEntity.ok(accomodationDTOs);
    }

    @RequestMapping(value = "getHotelById",
            method = RequestMethod.GET,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<AccomodationDTO> getHoltelById( Integer id ) {
        AccomodationDTO accomodationDTO = null;

        try {
            accomodationDTO = mainSearchServices.getHotelFromId(id);
        } catch (Exception e) {
            log.error("Exception: ", e);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
        }

        if ( accomodationDTO==null ) {
            return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);
        }

        return ResponseEntity.ok(accomodationDTO);
    }

    @RequestMapping(value = "getListRoomByHotelId",
            method = RequestMethod.GET,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<RoomDTO>> getListRoomByHotelId( Integer hotelId ) {
        List<RoomDTO> roomDTOs = null;

        try {
            roomDTOs = mainSearchServices.getListRoomByHotelId(hotelId);
        } catch (Exception e) {
            log.error("Exception: ", e);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
        }

        if ( roomDTOs==null ) {
            return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);
        }

        return ResponseEntity.ok(roomDTOs);
    }

}

然后,我有一个名为PlaceSearcherControllerTest的JUnit测试类,其中包含以下代码:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PlaceSearcherControllerTest {

    @Autowired
    private PlaceSearcherController placeSearcherController;

    @Test
    public void placeSearcherControllerTest() {
        System.out.println("placeSearcherControllerTest START");
        System.out.println("placeSearcherControllerTest END");
    }

}

此时,PlaceSearcherControllerTest()方法不执行任何操作,我只是尝试运行一个定义到获取PlaceSearcherController控制器实例的JUnit类中的JUnit测试方法。

因此,问题是运行前面的PlaceSearcherControllerTest()测试方法,我会得到以下错误消息:

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:392)
    at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.getOrFindConfigurationClasses(SpringBootTestContextBootstrapper.java:173)
    at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.processMergedContextConfiguration(SpringBootTestContextBootstrapper.java:133)
    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:78)
    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:422)
    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 org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:36)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:96)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)


Process finished with exit code -1

这是为什么?如何解决这个问题并将PlaceSearcherController实例正确地获取到JUnit测试类中?

错误消息告诉我:

找不到@SpringBootConfiguration,您需要使用@ContextConfiguration或@SpringBootTest(Classes=...)用你的测试

共有1个答案

陈翰林
2023-03-14

让我们假设您的控制器位于com.example.foo.controller中,而您的测试位于同一目录中。现在我们假设您的主类(@SpringBootApplication)位于com.example.foo.app中。您可能已经调优了组件扫描指令,因为您有一个不寻常的设置。

这对测试也有影响!测试支持将尝试通过查找父包中的匹配项来定位@SpringBootConfiguration(@SpringBootApplication@SpringBootConfiguration)。如果不是,它将抛出此异常。

关键是单据的这一部分

@SpringBootTest(classes = MyApp.class, webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
 类似资料: