【问题标题】:How to test Rest Controller with static util invocation using JUnit and Mockito如何使用 JUnit 和 Mockito 通过静态 util 调用测试 Rest Controller
【发布时间】:2023-03-24 03:52:01
【问题描述】:

我有带有方法 create(validation using util class + databaseService(databaseDao + caching ))

@RestController
@RequestMapping("files")
public class FilesController {
    private IDbFilesDao dbFilesService;
    private Map<String, Table> tables;

    public FilesController(IDbFilesDao dbFilesService, Map<String, Table> tables) {
        this.dbFilesService = dbFilesService;
        this.tables = tables;
    }

    @PostMapping("{table}")
    public ResponseEntity createTable(@PathVariable("table") String tableName,
                                         @RequestBody File file) {
        FilesValidator.validateAdding(tableName, tables, file);

        dbFilesService.create(tableName, file);

        URI location = ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(file.getKey()).toUri();
        return ResponseEntity.created(location).build();
    }
}

我有一个测试:

@RunWith(SpringRunner.class)
@WebMvcTest(value = FilesController.class, secure = false)
public class FilesControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private IDbFilesDao dbFilesService;

    @MockBean
    private Map<String, Table> tables;

    @Test
    public void create() throws Exception {
        RequestBuilder requestBuilder = MockMvcRequestBuilders
                .post("/files/tableName")
                .accept(MediaType.APPLICATION_JSON)
                .content(POST_JSON_BODY)
                .contentType(MediaType.APPLICATION_JSON);
        MvcResult result = mockMvc.perform(requestBuilder).andReturn();
        MockHttpServletResponse response = result.getResponse();
        assertEquals(HttpStatus.CREATED.value(), response.getStatus());
    }
}

只有在@RestContoller 中没有这一行时它才能正常工作:

FilesValidator.validateAdding(tableName, tables, file);

此行 - 404 未找到。

FilesValidator - 具有静态方法的实用程序类。它检查数据是否有效并且什么都不做或抛出带有状态码的运行时异常(例如 404)。

如何在不删除 Validation 的情况下修复它?

【问题讨论】:

    标签: java spring junit mockito integration-testing


    【解决方案1】:

    1) 将验证器调用移至包级方法并进行小重构:

    @PostMapping("{table}")
        public ResponseEntity createTable(@PathVariable("table") String tableName,
                                             @RequestBody File file) {
            validateAdding(tableName, tables, file);
            ...
    }
    
    validateAdding(String tableName, Map<String, Table> tables, File file){
        FilesValidator.validateAdding(tableName, tables, file);
    }
    

    2) 在测试中窥探控制器:

    @SpyBean
    private FilesController filesControllerSpy;
    

    3)validateAdding 方法什么都不做:

    @Test
    public void create() throws Exception {
    
       doNothing().when(filesControllerSpy)
         .validateAdding(any(String.class), any(Map.class), any(File.class));
       ...
    

    【讨论】:

    • 它有效,谢谢!但我能问点什么吗?如果我将此类作为具有非静态方法的 Bean 而不是 util 类,我可以忽略模拟此调用。为什么?使用静态我有一个例外,作为一个豆使用我可以忽略它。
    • 这意味着 Mockito.doNothing() 并忽略它在使用非静态方法的情况下具有相同的结果
    • 然后你可以模拟那个 bean,不需要更多的设置,因为模拟的 void 方法默认什么都不做
    • 在这种情况下,我将拥有从未使用过的@MockBean
    • 它会被使用,但作为一个什么都不做的模拟调用
    猜你喜欢
    • 2023-02-13
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    • 2021-11-06
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多