繁体   English   中英

Controller 单元测试使用 JUnit 5 in Spring Boot v3.0.1

[英]Controller unit tests using JUnit 5 in Spring Boot v3.0.1

我正在尝试在 Spring Boot (v3.0.1) 中使用 JUnit 5 为 controller class 编写单元测试。 我被以下错误困住了。 我已经包含了 controller 和测试类供您查看。

如果我添加@NoArgsConstructor ,编译器会抱怨 final 字段未初始化。

如果除了提供默认构造函数之外我还注入了 taskservice 和 taskmapper,测试将失败并抛出错误 - this.taskService 是 null。

考虑到可测试性,谁能告诉我在 controller 中注入依赖项的正确方法是什么。

如果我遗漏了什么,请告诉我。

        org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.ttk.taskitems.controller.TaskController]: No default constructor found

        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:146)
        at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder.instantiateIfNecessary(StandaloneMockMvcBuilder.java:157)
        at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder.<init>(StandaloneMockMvcBuilder.java:151)
        at org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup(MockMvcBuilders.java:76)
        at com.ttk.taskitems.controller.TaskControllerUnitTests.setUp(TaskControllerUnitTests.java:59)
        .
        .
        at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
        at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
    Caused by: java.lang.NoSuchMethodException: com.ttk.taskitems.controller.TaskController.<init>()
        at java.base/java.lang.Class.getConstructor0(Class.java:3585)
        at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2754)
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141)
        ... 78 more     
        

任务控制器 class

    @RestController
    @RequestMapping(path = "/api/v1/tasks", produces = MediaType.APPLICATION_JSON_VALUE)
    @RequiredArgsConstructor
    public class TaskController {

        private final TaskService taskService;
        private final TaskMapper map;

        @GetMapping("/{id}")
        public ResponseEntity<TaskDto> findById(@PathVariable Long id) {
            Optional<Task> item = taskService.findByTaskId(id);
            return ResponseEntity.status(HttpStatus.OK).body(map.taskDto(item.get()));
        }
        }
    }

任务控制器单元测试 class

    @ExtendWith(MockitoExtension.class)
    public class TaskControllerUnitTests {


        @Mock
        private TaskService taskService;

        @InjectMocks
        private TaskControllerTaskController;

        @Mock
        private TaskMapper mapper;

        @Spy
        private Tasks task; //Test data builder 

        @SpyBean
        private ObjectMapper objectMapper;

        private Task task;
        private TaskDto taskDto;
        private MockMvc mockMvc;
        
        @BeforeEach
        public void setUp() {
            mockMvc = MockMvcBuilders.standaloneSetup(TaskController.class).build();
            task = Tasks.anItem(); // data builder
            TaskDto = Tasks.anItemDto(); // data builder
        }

        @Test
        void givenValidId_whenFindTaskById_thenReturnOK() throws Exception {
            Long id = 1L;
            when(taskService.findByTaskId(id)).thenReturn(Optional.of(task));
            when(mapper.toDto(task)).thenReturn(taskDto);

            mockMvc.perform(get("/api/v1/tasks/{id}", id)
                            .contentType(MediaType.APPLICATION_JSON;))
                    .andExpect(status().isOk())
                    .andExpect(content().json(objectMapper.writeValueAsString(taskDto)));
        }   
    }

您可以尝试自动装配这两个 bean:

    @RestController
    @RequestMapping(path = "/api/v1/tasks", produces = MediaType.APPLICATION_JSON_VALUE)
  
    public class TaskController {

        @Autowired
        private final TaskService taskService;

        @Autowired
        private final TaskMapper map;

        @GetMapping("/{id}")
        public ResponseEntity<TaskDto> findById(@PathVariable Long id) {
            Optional<Task> item = taskService.findByTaskId(id);
            return ResponseEntity.status(HttpStatus.OK).body(map.taskDto(item.get()));
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM