繁体   English   中英

MockBean 在 restful 服务中很奇怪

[英]MockBean is strange in restful services

我制作了 rest controller,调用@service class:

@Service
public class UnitServiceImpl extends HttpRequestServiceImpl implements UnitService {

    @Override
    public Unit addUnit(String unitName) {
        final Unit unit = new Unit();
        unit.setUnitName(unitName);
        return unitRepository.save(unit);
    }
    @Override
    public Unit getUnit(int id) {
        final Unit unit = unitRepository.findById(id);
        if (unit == null) {
            throw new EntityNotFoundException("Unit is not found");
        }
        return unit;
    }

    @Override
    public Iterable<Unit> getAllUnits() {
        return unitRepository.findAll();
    }
}

EnityNotFoundException 由 ExceptionHandlingController 处理:

@RestController
@ControllerAdvice
public class ExceptionHandlingController extends ResponseEntityExceptionHandler {

    @ExceptionHandler({RuntimeException.class})
    public final ResponseEntity<ErrorDetails> handleRuntimeException(RuntimeException ex, WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(),
                request.getDescription(false));
        HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
        if (ex.getClass() == EntityNotFoundException.class) {
            httpStatus = HttpStatus.NOT_FOUND;
        }
        return new ResponseEntity<>(errorDetails, httpStatus);
    }
}

单元 controller 只需调用 getUnit:

@RestController
public class UnitController {
    private final UnitService managementService;


    @PostMapping(value = "/unit", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Unit> addUnit(HttpServletRequest request) throws FieldsIsAbsentException {
        final String unitName = managementService.getParameter(request, "unit_name");

        final Unit unit = managementService.addUnit(unitName);
        return new ResponseEntity<>(unit, HttpStatus.CREATED);
    }
    public UnitController(UnitService managementService) {
        this.managementService = managementService;
    }

    @GetMapping(value = "/unit", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Iterable<Unit>> getAllUnits() {
        final Iterable<Unit> allUnits = managementService.getAllUnits();
        return new ResponseEntity<>(allUnits, HttpStatus.OK);
    }

    @GetMapping(value = "/unit/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Unit> getUnitById(@PathVariable("id") int id) {
        final Unit unit = managementService.getUnit(id);
        return new ResponseEntity<>(unit, HttpStatus.CREATED);
    }
}

现在我需要测试它们,并创建单元测试方法,必须检查 404 错误:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration
class UnitControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    UnitService unitService;

    @MockBean
    UnitRepository unitRepository;

    @Autowired
    private UnitController unitController;

    private List<Unit> units;

    @Before
    public void initUnits() {
        units = new ArrayList<>();
        Unit unitWithName = new Unit();
        unitWithName.setId(1);
        unitWithName.setUnitName("NameUnit");
        units.add(unitWithName);

        Unit unitWithoutName = new Unit();
        unitWithoutName.setId(2);
        units.add(unitWithoutName);
    }

    @Test
    void contextLoads() {
        Assert.assertNotNull(unitController);
    }

    @Test
    void testGetAllUnits() throws Exception {
        given(this.unitService.getAllUnits()).willReturn(units);
        mockMvc.perform(get("/unit"))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON));
    }

    @Test
    void testUnitNotFound() throws Exception {
        int id = -1;
        given(this.unitRepository.findById(id)).willReturn(null);
        mockMvc.perform(get("/unit/-1"))
                .andExpect(status().isNotFound())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON));
    }
}

当我运行测试时, testGetAllUnits 失败:

java.lang.AssertionError: Content type not set

并且 testUnitNotFound 失败并出现错误:

java.lang.AssertionError: Status expected:<404> but was:<201>

但是当我删除

@MockBean
UnitService unitService;

它会起作用的。 什么问题?


更新:我现在有类似的问题。 此代码插入有关单元的数据库信息。 但我为这个方法做了模拟。

    @Test
    void testAddUnit() throws Exception {
        Unit unit = new Unit();
        unit.setId(1);
        unit.setUnitName("TestUnit");

        given(unitService.addUnit("TestUnit")).willReturn(unit);
        mockMvc.perform(post("/unit").param("unit_name", "TestUnit"))
                .andExpect(status().isCreated())
                .andExpect(jsonPath("$.unitName").value("TestUnit"))
                .andExpect(jsonPath("$.id").value(1));
    }

你是 mocking 错误的 bean。 抛出异常的 bean 是服务 bean,所以模拟一下。

@Test
void testUnitNotFound() throws Exception {
    int id = -1;
    given(this.service.getUnit(id)).willThrow(new EntityNotFoundException("Unit is not found"));
    mockMvc.perform(get("/unit/-1"))
            .andExpect(status().isNotFound())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON));
}

testUnitNotFound()测试不起作用的问题是,您期望模拟存储库中的某些内容发生在同样被模拟的服务中。

如果服务被模拟,则不会调用任何实现。 仅返回默认值null 因此不会按预期抛出异常......

如果您想灵活地模拟大多数服务,但让其中的 rest 调用其原始实现,那么您应该更改:

@MockBean
UnitService unitService;

进入

@SpyBean
UnitService unitService;

暂无
暂无

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

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