AssertionError: Status expected:<201> but was:<400> JUnit POST Method
AssertionError: Status expected:<201> but was:<400> JUnit POST Method
我在尝试启动 JUnit 测试时遇到错误。当我调用该方法时,出现错误“java。lang.AssertionError:预期状态:<201> 但为:<400>”。
我做错了什么?
URL是对的,程序运行正常,但是测试没有通过
我的控制器:
@RestController
@RequestMapping(value = "addresses", produces = MediaType.APPLICATION_JSON_VALUE)
@RequiredArgsConstructor
public class AddressController {
private final AddressService addressService;
@GetMapping("/{id}")
public AddressResponse getAddress(@PathVariable Integer id) {
return addressService.getAddress(id)
.map(AddressResponse::convertToResponse)
.orElse(null);
}
@GetMapping
public List<AddressResponse> getAllAddresses() {
return addressService.getAllAddresses()
.stream()
.map(AddressResponse::convertToResponse)
.collect(Collectors.toList());
}
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public AddressResponse createAddress(@RequestBody AddressRequest request) {
return AddressResponse.convertToResponse(addressService.upsertAddress(request));
}
@PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public AddressResponse updateAddress(@RequestBody AddressRequest request) {
return AddressResponse.convertToResponse(addressService.upsertAddress(request));
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public Address deleteAddress(@PathVariable Integer id) {
return addressService.deleteAddress(id);
}
我的服务:
@Service
@RequiredArgsConstructor
public class AddressService {
private final AddressRepository addressRepository;
public Optional<Address> getAddress(Integer id) {
return addressRepository.findById(id);
}
public List<Address> getAllAddresses() {
return addressRepository.findAll();
}
public Address upsertAddress(@NonNull AddressRequest addressRequest) {
Address entity;
if (addressRequest.getId() == null) {
entity = new Address();
} else {
entity = addressRepository.findById(addressRequest.getId())
.orElseThrow(() -> new RuntimeException("Cannot find address by id"));
}
entity.setCity(addressRequest.getCity());
entity.setStreet(addressRequest.getStreet());
entity.setHouse(addressRequest.getHouse());
entity = addressRepository.save(entity);
return entity;
}
public Address deleteAddress(Integer id) {
Address address = null;
Optional<Address> optional = addressRepository.findById(id);
if (optional.isPresent()) {
address = optional.get();
addressRepository.deleteById(id);
}
return address;
}
}
}
还有我的测试Class:
@ExtendWith(MockitoExtension.class)
class AddressControllerTest {
@Mock
private AddressService addressService;
private com.second_bank.entities.Address address;
private List<Address> addressList;
@InjectMocks
private AddressController addressController;
@Autowired
MockMvc mockMvc;
@BeforeEach
public void setup() {
com.second_bank.entities.Address address = new com.second_bank.entities.Address("City", "Street", "House");
mockMvc = MockMvcBuilders.standaloneSetup(addressController).build();
}
@AfterEach
public void tearDown() {
address = null;
addressList = null;
}
@Test
void createAddress() throws Exception {
when(addressService.upsertAddress(any())).thenReturn(address);
mockMvc.perform(post("/addresses")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(address)))
.andExpect(status().isCreated());
verify(addressService, times(1)).upsertAddress(any());
}
我创建了一个将对象转换为 JSON
的方法
public static String asJsonString(final Object obj) {
try {
return new ObjectMapper().writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
DTO 响应:
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class AddressResponse {
private Integer id;
private String city;
private String street;
private String house;
public static AddressResponse convertToResponse(Address address){
return new AddressResponse(
address.getId(),
address.getCity(),
address.getStreet(),
address.getHouse()
);
}
}
DTO Request:
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class AddressRequest {
private Integer Id;
private String city;
private String street;
private String house;
}
不确定这是否是问题所在,但您似乎期望正文中有一个 AddressRequest 对象,但您在测试中发送了一个 Address 对象。如果 JSON 到对象的转换失败,它会 return 400 错误。
我在尝试启动 JUnit 测试时遇到错误。当我调用该方法时,出现错误“java。lang.AssertionError:预期状态:<201> 但为:<400>”。
我做错了什么? URL是对的,程序运行正常,但是测试没有通过
我的控制器:
@RestController
@RequestMapping(value = "addresses", produces = MediaType.APPLICATION_JSON_VALUE)
@RequiredArgsConstructor
public class AddressController {
private final AddressService addressService;
@GetMapping("/{id}")
public AddressResponse getAddress(@PathVariable Integer id) {
return addressService.getAddress(id)
.map(AddressResponse::convertToResponse)
.orElse(null);
}
@GetMapping
public List<AddressResponse> getAllAddresses() {
return addressService.getAllAddresses()
.stream()
.map(AddressResponse::convertToResponse)
.collect(Collectors.toList());
}
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public AddressResponse createAddress(@RequestBody AddressRequest request) {
return AddressResponse.convertToResponse(addressService.upsertAddress(request));
}
@PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public AddressResponse updateAddress(@RequestBody AddressRequest request) {
return AddressResponse.convertToResponse(addressService.upsertAddress(request));
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public Address deleteAddress(@PathVariable Integer id) {
return addressService.deleteAddress(id);
}
我的服务:
@Service
@RequiredArgsConstructor
public class AddressService {
private final AddressRepository addressRepository;
public Optional<Address> getAddress(Integer id) {
return addressRepository.findById(id);
}
public List<Address> getAllAddresses() {
return addressRepository.findAll();
}
public Address upsertAddress(@NonNull AddressRequest addressRequest) {
Address entity;
if (addressRequest.getId() == null) {
entity = new Address();
} else {
entity = addressRepository.findById(addressRequest.getId())
.orElseThrow(() -> new RuntimeException("Cannot find address by id"));
}
entity.setCity(addressRequest.getCity());
entity.setStreet(addressRequest.getStreet());
entity.setHouse(addressRequest.getHouse());
entity = addressRepository.save(entity);
return entity;
}
public Address deleteAddress(Integer id) {
Address address = null;
Optional<Address> optional = addressRepository.findById(id);
if (optional.isPresent()) {
address = optional.get();
addressRepository.deleteById(id);
}
return address;
}
}
}
还有我的测试Class:
@ExtendWith(MockitoExtension.class)
class AddressControllerTest {
@Mock
private AddressService addressService;
private com.second_bank.entities.Address address;
private List<Address> addressList;
@InjectMocks
private AddressController addressController;
@Autowired
MockMvc mockMvc;
@BeforeEach
public void setup() {
com.second_bank.entities.Address address = new com.second_bank.entities.Address("City", "Street", "House");
mockMvc = MockMvcBuilders.standaloneSetup(addressController).build();
}
@AfterEach
public void tearDown() {
address = null;
addressList = null;
}
@Test
void createAddress() throws Exception {
when(addressService.upsertAddress(any())).thenReturn(address);
mockMvc.perform(post("/addresses")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(address)))
.andExpect(status().isCreated());
verify(addressService, times(1)).upsertAddress(any());
}
我创建了一个将对象转换为 JSON
的方法public static String asJsonString(final Object obj) {
try {
return new ObjectMapper().writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
DTO 响应:
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class AddressResponse {
private Integer id;
private String city;
private String street;
private String house;
public static AddressResponse convertToResponse(Address address){
return new AddressResponse(
address.getId(),
address.getCity(),
address.getStreet(),
address.getHouse()
);
}
}
DTO Request:
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class AddressRequest {
private Integer Id;
private String city;
private String street;
private String house;
}
不确定这是否是问题所在,但您似乎期望正文中有一个 AddressRequest 对象,但您在测试中发送了一个 Address 对象。如果 JSON 到对象的转换失败,它会 return 400 错误。