Я сделал контроллер отдыха, который вызывает класс @service:
@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);
}
}
Контроллер устройства просто вызывает 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));
}