visit
@PutMapping(ManagerApi.CONTACT)
@Operation(summary = "Update contact")
public ContactResponse updateContact(
@RequestBody UpsertContactRequest request,
@RequestParam UUID id
) {
return contactService.update(id, request);
}
public record ContactResponse(
UUID id,
String name,
String phoneNumber
) {
}
public record UpsertContactRequest(
@NonNull String name,
@NonNull String phoneNumber
) {
}
@Entity
@Table(name = "contacts", schema = "cms")
@Builder
@Setter
public class ContactEntity extends AbstractEntity {
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
@Column(updatable = false, nullable = false)
protected UUID id;
@Column
private String name;
@Column(name = "phone_number", length = 10)
private String phoneNumber;
}
@Repository
public interface ContactJpaRepository
extends JpaRepository<ContactEntity, UUID> {
}
@SpringBootTest
public class SimpleContactTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ContactJpaRepository contactJpaRepository;
@Autowired
private ObjectMapper objectMapper;
@Test
@SneakyThrows
public void updateContactTest() {
var oldEntity = ContactEntity.builder()
.name("old name")
.phoneNumber("0000000000")
.build();
var savedEntity = contactJpaRepository.save(oldEntity);
var request = new CreateContactRequest("name", "1112223344");
var contentAsString = mockMvc.perform(
MockMvcRequestBuilders.put(
ManagerApi.CONTACT,, savedEntity.getId())
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(request)))
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn()
.getResponse()
.getContentAsString();
var response = objectMapper.readValue(contentAsString, ContactResponse.class);
Assertions.assertEquals(request.name(), response.name());
Assertions.assertEquals(request.phoneNumber(), response.phoneNumber());
Assertions.assertNotNull(response.id());
Optional<ContactEntity> entity = contactJpaRepository.findById(response.id());
Assertions.assertTrue(entity.isPresent());
Assertions.assertEquals(response.name(), entity.get().getName());
Assertions.assertEquals(response.phoneNumber(), entity.get().getPhoneNumber());
}
}
Optimize regularly used logic - this will save you an enormous amount of time in the future.
@DBUnit(
caseInsensitiveStrategy = Orthography.LOWERCASE,
batchedStatements = true,
allowEmptyFields = true,
schema = "cms"
)
@SpringBootTest
public class SimpleContactTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
@SneakyThrows
@DataSet(
cleanBefore = true,
value = "controller/contact/update.success/dataset.json"
)
@ExpectedDataSet("controller/contact/update.success/dataset-expected.json")
public void updateContactTest() {
var request = new CreateContactRequest("name", "1112223344");
var contentAsString = mockMvc.perform(
MockMvcRequestBuilders.put(
ManagerApi.CONTACT,
"7624f434-cbc5-11ec-9d64-0242ac120002")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(request)))
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn()
.getResponse()
.getContentAsString();
var response = objectMapper.readValue(contentAsString, ContactResponse.class);
Assertions.assertEquals(request.name(), response.name());
Assertions.assertEquals(request.phoneNumber(), response.phoneNumber());
Assertions.assertNotNull(response.id());
}
}
## controller/contact/update.success/dataset.json
{
"contacts": [
{
"id": "7624f434-cbc5-11ec-9d64-0242ac120002",
"name": "old name",
"phone_number": "0000000000"
}
]
}
## controller/contact/update.success/dataset-expected.json
{
"contacts": [
{
"id": "7624f434-cbc5-11ec-9d64-0242ac120002",
"name": "name",
"phone_number": "1112223344"
}
]
}
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ArgumentsSource(JsonFileSourceProvider.class)
public @interface JsonFileSource {
String file() default "";
String expectFile() default "";
}
public class JsonFileSourceProvider
implements AnnotationConsumer<JsonFileSource>, ArgumentsProvider {
private final List<String> resources = new ArrayList<>();
@Override
public void accept(JsonFileSource jsonFileSource) {
addResource(jsonFileSource.file());
addResource(jsonFileSource.expectFile());
}
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return Stream.of(resources)
.map(
r -> r.stream()
.map(this::getJsonResource)
.toArray()
)
.map(Arguments::of);
}
private void addResource(String resource) {
if (!resource.isEmpty()) {
this.resources.add(resource);
}
}
private String getJsonResource(String file) {
try {
return new String(
Files.readAllBytes(
ResourceUtils.getFile(String.format("classpath:%s", file)).toPath()
)
);
} catch (final IOException err) {
return null;
}
}
}
@DBUnit(
caseInsensitiveStrategy = Orthography.LOWERCASE,
batchedStatements = true,
allowEmptyFields = true,
schema = "cms"
)
@SpringBootTest
public class SimpleContactTest {
@Autowired
private MockMvc mockMvc;
@SneakyThrows
@ParameterizedTest
@DataSet(
cleanBefore = true,
value = "controller/contact/update.success/dataset.json"
)
@ExpectedDataSet("controller/contact/update.success/dataset-expected.json")
@JsonFileSource(
file = "controller/contact/update.success/request.json",
expectFile = "controller/contact/update.success/response.json"
)
public void updateContactTest(String request, String response) {
mockMvc.perform(
MockMvcRequestBuilders.put(
ManagerApi.CONTACT, "7624f434-cbc5-11ec-9d64-0242ac120002")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.content(request))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().json(response));
}
}
## controller/contact/update.success/request.json
{
"name": "old name",
"phone_number": "0000000000"
}
## controller/contact/update.success/response.json
{
"name": "name",
"phone_number": "1112223344"
}