Apply spring-format plugin

This commit is contained in:
Dave Syer 2020-01-03 11:22:05 +00:00
parent 82cb521d63
commit 4e1f87407d
36 changed files with 1128 additions and 1168 deletions

15
pom.xml
View file

@ -28,6 +28,7 @@
<wro4j.version>1.8.0</wro4j.version>
<jacoco.version>0.8.5</jacoco.version>
<spring-format.version>0.0.17</spring-format.version>
</properties>
@ -130,6 +131,20 @@
<build>
<plugins>
<plugin>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
<version>${spring-format.version}</version>
<!-- run ./mvnw spring-javaformat:apply to apply -->
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>

View file

@ -31,6 +31,7 @@ import javax.persistence.MappedSuperclass;
*/
@MappedSuperclass
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

View file

@ -18,10 +18,9 @@ package org.springframework.samples.petclinic.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
/**
* Simple JavaBean domain object adds a name property to <code>BaseEntity</code>. Used as a base class for objects
* needing these properties.
* Simple JavaBean domain object adds a name property to <code>BaseEntity</code>. Used as
* a base class for objects needing these properties.
*
* @author Ken Krebs
* @author Juergen Hoeller

View file

@ -18,4 +18,3 @@
* The classes in this package represent utilities used by the domain.
*/
package org.springframework.samples.petclinic.model;

View file

@ -45,6 +45,7 @@ import org.springframework.samples.petclinic.model.Person;
@Entity
@Table(name = "owners")
public class Owner extends Person {
@Column(name = "address")
@NotEmpty
private String address;
@ -98,8 +99,7 @@ public class Owner extends Person {
public List<Pet> getPets() {
List<Pet> sortedPets = new ArrayList<>(getPetsInternal());
PropertyComparator.sort(sortedPets,
new MutableSortDefinition("name", true, true));
PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
return Collections.unmodifiableList(sortedPets);
}
@ -112,7 +112,6 @@ public class Owner extends Person {
/**
* Return the Pet with the given name, or null if none found for this Owner.
*
* @param name to test
* @return true if pet name is already in use
*/
@ -122,7 +121,6 @@ public class Owner extends Person {
/**
* Return the Pet with the given name, or null if none found for this Owner.
*
* @param name to test
* @return true if pet name is already in use
*/
@ -144,9 +142,9 @@ public class Owner extends Person {
public String toString() {
return new ToStringCreator(this)
.append("id", this.getId()).append("new", this.isNew())
.append("lastName", this.getLastName())
.append("firstName", this.getFirstName()).append("address", this.address)
.append("city", this.city).append("telephone", this.telephone).toString();
.append("id", this.getId()).append("new", this.isNew()).append("lastName", this.getLastName())
.append("firstName", this.getFirstName()).append("address", this.address).append("city", this.city)
.append("telephone", this.telephone).toString();
}
}

View file

@ -40,9 +40,10 @@ import java.util.Map;
class OwnerController {
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
private final OwnerRepository owners;
private VisitRepository visits;
private final OwnerRepository owners;
private VisitRepository visits;
public OwnerController(OwnerRepository clinicService, VisitRepository visits) {
this.owners = clinicService;
@ -65,7 +66,8 @@ class OwnerController {
public String processCreationForm(@Valid Owner owner, BindingResult result) {
if (result.hasErrors()) {
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
} else {
}
else {
this.owners.save(owner);
return "redirect:/owners/" + owner.getId();
}
@ -91,11 +93,13 @@ class OwnerController {
// no owners found
result.rejectValue("lastName", "notFound", "not found");
return "owners/findOwners";
} else if (results.size() == 1) {
}
else if (results.size() == 1) {
// 1 owner found
owner = results.iterator().next();
return "redirect:/owners/" + owner.getId();
} else {
}
else {
// multiple owners found
model.put("selections", results);
return "owners/ownersList";
@ -110,10 +114,12 @@ class OwnerController {
}
@PostMapping("/owners/{ownerId}/edit")
public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, @PathVariable("ownerId") int ownerId) {
public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result,
@PathVariable("ownerId") int ownerId) {
if (result.hasErrors()) {
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
} else {
}
else {
owner.setId(ownerId);
this.owners.save(owner);
return "redirect:/owners/{ownerId}";
@ -122,7 +128,6 @@ class OwnerController {
/**
* Custom handler for displaying an owner.
*
* @param ownerId the ID of the owner to display
* @return a ModelMap with the model attributes for the view
*/

View file

@ -23,9 +23,10 @@ import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
/**
* Repository class for <code>Owner</code> domain objects All method names are compliant with Spring Data naming
* conventions so this interface can easily be extended for Spring Data.
* See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
* Repository class for <code>Owner</code> domain objects All method names are compliant
* with Spring Data naming conventions so this interface can easily be extended for Spring
* Data. See:
* https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
*
* @author Ken Krebs
* @author Juergen Hoeller
@ -60,5 +61,4 @@ public interface OwnerRepository extends Repository<Owner, Integer> {
*/
void save(Owner owner);
}

View file

@ -100,8 +100,7 @@ public class Pet extends NamedEntity {
public List<Visit> getVisits() {
List<Visit> sortedVisits = new ArrayList<>(getVisitsInternal());
PropertyComparator.sort(sortedVisits,
new MutableSortDefinition("date", false, false));
PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false));
return Collections.unmodifiableList(sortedVisits);
}

View file

@ -35,7 +35,9 @@ import java.util.Collection;
class PetController {
private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
private final PetRepository pets;
private final OwnerRepository owners;
public PetController(PetRepository pets, OwnerRepository owners) {
@ -73,14 +75,15 @@ class PetController {
@PostMapping("/pets/new")
public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) {
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) {
result.rejectValue("name", "duplicate", "already exists");
}
owner.addPet(pet);
if (result.hasErrors()) {
model.put("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
} else {
}
else {
this.pets.save(pet);
return "redirect:/owners/{ownerId}";
}
@ -99,7 +102,8 @@ class PetController {
pet.setOwner(owner);
model.put("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
} else {
}
else {
owner.addPet(pet);
this.pets.save(pet);
return "redirect:/owners/{ownerId}";

View file

@ -22,9 +22,10 @@ import org.springframework.data.repository.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
* Repository class for <code>Pet</code> domain objects All method names are compliant with Spring Data naming
* conventions so this interface can easily be extended for Spring Data.
* See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
* Repository class for <code>Pet</code> domain objects All method names are compliant
* with Spring Data naming conventions so this interface can easily be extended for Spring
* Data. See:
* https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
*
* @author Ken Krebs
* @author Juergen Hoeller
@ -56,4 +57,3 @@ public interface PetRepository extends Repository<Pet, Integer> {
void save(Pet pet);
}

View file

@ -21,8 +21,7 @@ import javax.persistence.Table;
import org.springframework.samples.petclinic.model.NamedEntity;
/**
* @author Juergen Hoeller
* Can be Cat, Dog, Hamster...
* @author Juergen Hoeller Can be Cat, Dog, Hamster...
*/
@Entity
@Table(name = "types")

View file

@ -24,9 +24,10 @@ import org.springframework.format.Formatter;
import org.springframework.stereotype.Component;
/**
* Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting from Spring 3.0, Formatters have
* come as an improvement in comparison to legacy PropertyEditors. See the following links for more details: - The
* Spring ref doc: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#format
* Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting
* from Spring 3.0, Formatters have come as an improvement in comparison to legacy
* PropertyEditors. See the following links for more details: - The Spring ref doc:
* https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#format
*
* @author Mark Fisher
* @author Juergen Hoeller
@ -37,7 +38,6 @@ public class PetTypeFormatter implements Formatter<PetType> {
private final PetRepository pets;
@Autowired
public PetTypeFormatter(PetRepository pets) {
this.pets = pets;

View file

@ -22,7 +22,8 @@ import org.springframework.validation.Validator;
/**
* <code>Validator</code> for <code>Pet</code> forms.
* <p>
* We're not using Bean Validation annotations here because it is easier to define such validation rule in Java.
* We're not using Bean Validation annotations here because it is easier to define such
* validation rule in Java.
* </p>
*
* @author Ken Krebs
@ -60,5 +61,4 @@ public class PetValidator implements Validator {
return Pet.class.isAssignableFrom(clazz);
}
}

View file

@ -41,8 +41,8 @@ import org.springframework.web.bind.annotation.PostMapping;
class VisitController {
private final VisitRepository visits;
private final PetRepository pets;
private final PetRepository pets;
public VisitController(VisitRepository visits, PetRepository pets) {
this.visits = visits;
@ -55,12 +55,9 @@ class VisitController {
}
/**
* Called before each and every @RequestMapping annotated method.
* 2 goals:
* - Make sure we always have fresh data
* - Since we do not use the session scope, make sure that Pet object always has an id
* (Even though id is not part of the form fields)
*
* Called before each and every @RequestMapping annotated method. 2 goals: - Make sure
* we always have fresh data - Since we do not use the session scope, make sure that
* Pet object always has an id (Even though id is not part of the form fields)
* @param petId
* @return Pet
*/
@ -85,7 +82,8 @@ class VisitController {
public String processNewVisitForm(@Valid Visit visit, BindingResult result) {
if (result.hasErrors()) {
return "pets/createOrUpdateVisitForm";
} else {
}
else {
this.visits.save(visit);
return "redirect:/owners/{ownerId}";
}

View file

@ -30,8 +30,8 @@ class CrashController {
@GetMapping("/oups")
public String triggerException() {
throw new RuntimeException("Expected: controller used to showcase what "
+ "happens when an exception is thrown");
throw new RuntimeException(
"Expected: controller used to showcase what " + "happens when an exception is thrown");
}
}

View file

@ -16,7 +16,6 @@
package org.springframework.samples.petclinic.system;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@ -27,4 +26,5 @@ class WelcomeController {
public String welcome() {
return "welcome";
}
}

View file

@ -46,7 +46,8 @@ import org.springframework.samples.petclinic.model.Person;
public class Vet extends Person {
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"), inverseJoinColumns = @JoinColumn(name = "specialty_id"))
@JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"),
inverseJoinColumns = @JoinColumn(name = "specialty_id"))
private Set<Specialty> specialties;
protected Set<Specialty> getSpecialtiesInternal() {
@ -63,8 +64,7 @@ public class Vet extends Person {
@XmlElement
public List<Specialty> getSpecialties() {
List<Specialty> sortedSpecs = new ArrayList<>(getSpecialtiesInternal());
PropertyComparator.sort(sortedSpecs,
new MutableSortDefinition("name", true, true));
PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true));
return Collections.unmodifiableList(sortedSpecs);
}

View file

@ -23,9 +23,10 @@ import org.springframework.data.repository.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
* Repository class for <code>Vet</code> domain objects All method names are compliant with Spring Data naming
* conventions so this interface can easily be extended for Spring Data.
* See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
* Repository class for <code>Vet</code> domain objects All method names are compliant
* with Spring Data naming conventions so this interface can easily be extended for Spring
* Data. See:
* https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
*
* @author Ken Krebs
* @author Juergen Hoeller
@ -36,12 +37,10 @@ public interface VetRepository extends Repository<Vet, Integer> {
/**
* Retrieve all <code>Vet</code>s from the data store.
*
* @return a <code>Collection</code> of <code>Vet</code>s
*/
@Transactional(readOnly = true)
@Cacheable("vets")
Collection<Vet> findAll() throws DataAccessException;
}

View file

@ -22,8 +22,8 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Simple domain object representing a list of veterinarians. Mostly here to be used for the 'vets' {@link
* org.springframework.web.servlet.view.xml.MarshallingView}.
* Simple domain object representing a list of veterinarians. Mostly here to be used for
* the 'vets' {@link org.springframework.web.servlet.view.xml.MarshallingView}.
*
* @author Arjen Poutsma
*/

View file

@ -22,9 +22,10 @@ import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.BaseEntity;
/**
* Repository class for <code>Visit</code> domain objects All method names are compliant with Spring Data naming
* conventions so this interface can easily be extended for Spring Data.
* See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
* Repository class for <code>Visit</code> domain objects All method names are compliant
* with Spring Data naming conventions so this interface can easily be extended for Spring
* Data. See:
* https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
*
* @author Ken Krebs
* @author Juergen Hoeller
@ -35,7 +36,6 @@ public interface VisitRepository extends Repository<Visit, Integer> {
/**
* Save a <code>Visit</code> to the data store, either inserting or updating it.
*
* @param visit the <code>Visit</code> to save
* @see BaseEntity#isNew
*/

View file

@ -32,4 +32,5 @@ class PetclinicIntegrationTests {
vets.findAll();
vets.findAll(); // served from cache
}
}

View file

@ -49,8 +49,7 @@ class ValidatorTests {
person.setLastName("smith");
Validator validator = createValidator();
Set<ConstraintViolation<Person>> constraintViolations = validator
.validate(person);
Set<ConstraintViolation<Person>> constraintViolations = validator.validate(person);
assertThat(constraintViolations).hasSize(1);
ConstraintViolation<Person> violation = constraintViolations.iterator().next();

View file

@ -89,33 +89,22 @@ class OwnerControllerTests {
@Test
void testInitCreationForm() throws Exception {
mockMvc.perform(get("/owners/new"))
.andExpect(status().isOk())
.andExpect(model().attributeExists("owner"))
mockMvc.perform(get("/owners/new")).andExpect(status().isOk()).andExpect(model().attributeExists("owner"))
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
}
@Test
void testProcessCreationFormSuccess() throws Exception {
mockMvc.perform(post("/owners/new")
.param("firstName", "Joe")
.param("lastName", "Bloggs")
.param("address", "123 Caramel Street")
.param("city", "London")
.param("telephone", "01316761638")
)
mockMvc.perform(post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs")
.param("address", "123 Caramel Street").param("city", "London").param("telephone", "01316761638"))
.andExpect(status().is3xxRedirection());
}
@Test
void testProcessCreationFormHasErrors() throws Exception {
mockMvc.perform(post("/owners/new")
.param("firstName", "Joe")
.param("lastName", "Bloggs")
.param("city", "London")
)
.andExpect(status().isOk())
.andExpect(model().attributeHasErrors("owner"))
mockMvc.perform(
post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs").param("city", "London"))
.andExpect(status().isOk()).andExpect(model().attributeHasErrors("owner"))
.andExpect(model().attributeHasFieldErrors("owner", "address"))
.andExpect(model().attributeHasFieldErrors("owner", "telephone"))
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
@ -123,36 +112,26 @@ class OwnerControllerTests {
@Test
void testInitFindForm() throws Exception {
mockMvc.perform(get("/owners/find"))
.andExpect(status().isOk())
.andExpect(model().attributeExists("owner"))
mockMvc.perform(get("/owners/find")).andExpect(status().isOk()).andExpect(model().attributeExists("owner"))
.andExpect(view().name("owners/findOwners"));
}
@Test
void testProcessFindFormSuccess() throws Exception {
given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner()));
mockMvc.perform(get("/owners"))
.andExpect(status().isOk())
.andExpect(view().name("owners/ownersList"));
mockMvc.perform(get("/owners")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList"));
}
@Test
void testProcessFindFormByLastName() throws Exception {
given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george));
mockMvc.perform(get("/owners")
.param("lastName", "Franklin")
)
.andExpect(status().is3xxRedirection())
mockMvc.perform(get("/owners").param("lastName", "Franklin")).andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID));
}
@Test
void testProcessFindFormNoOwnersFound() throws Exception {
mockMvc.perform(get("/owners")
.param("lastName", "Unknown Surname")
)
.andExpect(status().isOk())
mockMvc.perform(get("/owners").param("lastName", "Unknown Surname")).andExpect(status().isOk())
.andExpect(model().attributeHasFieldErrors("owner", "lastName"))
.andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound"))
.andExpect(view().name("owners/findOwners"));
@ -160,8 +139,7 @@ class OwnerControllerTests {
@Test
void testInitUpdateOwnerForm() throws Exception {
mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID))
.andExpect(status().isOk())
mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)).andExpect(status().isOk())
.andExpect(model().attributeExists("owner"))
.andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin"))))
.andExpect(model().attribute("owner", hasProperty("firstName", is("George"))))
@ -173,25 +151,16 @@ class OwnerControllerTests {
@Test
void testProcessUpdateOwnerFormSuccess() throws Exception {
mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID)
.param("firstName", "Joe")
.param("lastName", "Bloggs")
.param("address", "123 Caramel Street")
.param("city", "London")
.param("telephone", "01616291589")
)
.andExpect(status().is3xxRedirection())
mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe")
.param("lastName", "Bloggs").param("address", "123 Caramel Street").param("city", "London")
.param("telephone", "01616291589")).andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/owners/{ownerId}"));
}
@Test
void testProcessUpdateOwnerFormHasErrors() throws Exception {
mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID)
.param("firstName", "Joe")
.param("lastName", "Bloggs")
.param("city", "London")
)
.andExpect(status().isOk())
mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe")
.param("lastName", "Bloggs").param("city", "London")).andExpect(status().isOk())
.andExpect(model().attributeHasErrors("owner"))
.andExpect(model().attributeHasFieldErrors("owner", "address"))
.andExpect(model().attributeHasFieldErrors("owner", "telephone"))
@ -200,8 +169,7 @@ class OwnerControllerTests {
@Test
void testShowOwner() throws Exception {
mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID))
.andExpect(status().isOk())
mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)).andExpect(status().isOk())
.andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin"))))
.andExpect(model().attribute("owner", hasProperty("firstName", is("George"))))
.andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St."))))
@ -224,8 +192,8 @@ class OwnerControllerTests {
@Override
public void describeTo(Description description) {
description.appendText("Max did not have any visits");
}})))
.andExpect(view().name("owners/ownerDetails"));
}
}))).andExpect(view().name("owners/ownerDetails"));
}
}

View file

@ -39,14 +39,12 @@ import org.springframework.test.web.servlet.MockMvc;
* @author Colin But
*/
@WebMvcTest(value = PetController.class,
includeFilters = @ComponentScan.Filter(
value = PetTypeFormatter.class,
type = FilterType.ASSIGNABLE_TYPE))
includeFilters = @ComponentScan.Filter(value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE))
class PetControllerTests {
private static final int TEST_OWNER_ID = 1;
private static final int TEST_PET_ID = 1;
private static final int TEST_PET_ID = 1;
@Autowired
private MockMvc mockMvc;
@ -70,65 +68,45 @@ class PetControllerTests {
@Test
void testInitCreationForm() throws Exception {
mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID))
.andExpect(status().isOk())
.andExpect(view().name("pets/createOrUpdatePetForm"))
.andExpect(model().attributeExists("pet"));
mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)).andExpect(status().isOk())
.andExpect(view().name("pets/createOrUpdatePetForm")).andExpect(model().attributeExists("pet"));
}
@Test
void testProcessCreationFormSuccess() throws Exception {
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID)
.param("name", "Betty")
.param("type", "hamster")
.param("birthDate", "2015-02-12")
)
.andExpect(status().is3xxRedirection())
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty")
.param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/owners/{ownerId}"));
}
@Test
void testProcessCreationFormHasErrors() throws Exception {
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID)
.param("name", "Betty")
.param("birthDate", "2015-02-12")
)
.andExpect(model().attributeHasNoErrors("owner"))
.andExpect(model().attributeHasErrors("pet"))
.andExpect(model().attributeHasFieldErrors("pet", "type"))
.andExpect(model().attributeHasFieldErrorCode("pet", "type", "required"))
.andExpect(status().isOk())
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty").param("birthDate",
"2015-02-12")).andExpect(model().attributeHasNoErrors("owner"))
.andExpect(model().attributeHasErrors("pet")).andExpect(model().attributeHasFieldErrors("pet", "type"))
.andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")).andExpect(status().isOk())
.andExpect(view().name("pets/createOrUpdatePetForm"));
}
@Test
void testInitUpdateForm() throws Exception {
mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID))
.andExpect(status().isOk())
.andExpect(model().attributeExists("pet"))
.andExpect(status().isOk()).andExpect(model().attributeExists("pet"))
.andExpect(view().name("pets/createOrUpdatePetForm"));
}
@Test
void testProcessUpdateFormSuccess() throws Exception {
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)
.param("name", "Betty")
.param("type", "hamster")
.param("birthDate", "2015-02-12")
)
.andExpect(status().is3xxRedirection())
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty")
.param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/owners/{ownerId}"));
}
@Test
void testProcessUpdateFormHasErrors() throws Exception {
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)
.param("name", "Betty")
.param("birthDate", "2015/02/12")
)
.andExpect(model().attributeHasNoErrors("owner"))
.andExpect(model().attributeHasErrors("pet"))
.andExpect(status().isOk())
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty")
.param("birthDate", "2015/02/12")).andExpect(model().attributeHasNoErrors("owner"))
.andExpect(model().attributeHasErrors("pet")).andExpect(status().isOk())
.andExpect(view().name("pets/createOrUpdatePetForm"));
}

View file

@ -75,7 +75,6 @@ class PetTypeFormatterTests {
/**
* Helper method to produce some sample pet types just for test purpose
*
* @return {@link Collection} of {@link PetType}
*/
private List<PetType> makePetTypes() {

View file

@ -57,28 +57,21 @@ class VisitControllerTests {
@Test
void testInitNewVisitForm() throws Exception {
mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID))
.andExpect(status().isOk())
mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)).andExpect(status().isOk())
.andExpect(view().name("pets/createOrUpdateVisitForm"));
}
@Test
void testProcessNewVisitFormSuccess() throws Exception {
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)
.param("name", "George")
.param("description", "Visit Description")
)
.andExpect(status().is3xxRedirection())
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George")
.param("description", "Visit Description")).andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/owners/{ownerId}"));
}
@Test
void testProcessNewVisitFormHasErrors() throws Exception {
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)
.param("name", "George")
)
.andExpect(model().attributeHasErrors("visit"))
.andExpect(status().isOk())
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George"))
.andExpect(model().attributeHasErrors("visit")).andExpect(status().isOk())
.andExpect(view().name("pets/createOrUpdateVisitForm"));
}

View file

@ -40,15 +40,24 @@ import org.springframework.transaction.annotation.Transactional;
/**
* Integration test of the Service and the Repository layer.
* <p>
* ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided by the Spring
* TestContext Framework: </p> <ul> <li><strong>Spring IoC container caching</strong> which spares us unnecessary set up
* time between test execution.</li> <li><strong>Dependency Injection</strong> of test fixture instances, meaning that
* we don't need to perform application context lookups. See the use of {@link Autowired @Autowired} on the <code>{@link
* ClinicServiceTests#clinicService clinicService}</code> instance variable, which uses autowiring <em>by
* type</em>. <li><strong>Transaction management</strong>, meaning each test method is executed in its own transaction,
* which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there
* is no need for a teardown or cleanup script. <li> An {@link org.springframework.context.ApplicationContext
* ApplicationContext} is also inherited and can be used for explicit bean lookup if necessary. </li> </ul>
* ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided
* by the Spring TestContext Framework:
* </p>
* <ul>
* <li><strong>Spring IoC container caching</strong> which spares us unnecessary set up
* time between test execution.</li>
* <li><strong>Dependency Injection</strong> of test fixture instances, meaning that we
* don't need to perform application context lookups. See the use of
* {@link Autowired @Autowired} on the <code>{@link
* ClinicServiceTests#clinicService clinicService}</code> instance variable, which uses
* autowiring <em>by type</em>.
* <li><strong>Transaction management</strong>, meaning each test method is executed in
* its own transaction, which is automatically rolled back by default. Thus, even if tests
* insert or otherwise change database state, there is no need for a teardown or cleanup
* script.
* <li>An {@link org.springframework.context.ApplicationContext ApplicationContext} is
* also inherited and can be used for explicit bean lookup if necessary.</li>
* </ul>
*
* @author Ken Krebs
* @author Rod Johnson

View file

@ -22,8 +22,8 @@ import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.samples.petclinic.model.BaseEntity;
/**
* Utility methods for handling entities. Separate from the BaseEntity class mainly because of dependency on the
* ORM-associated ObjectRetrievalFailureException.
* Utility methods for handling entities. Separate from the BaseEntity class mainly
* because of dependency on the ORM-associated ObjectRetrievalFailureException.
*
* @author Juergen Hoeller
* @author Sam Brannen
@ -34,7 +34,6 @@ public abstract class EntityUtils {
/**
* Look up the entity of the given class with the given id in the given collection.
*
* @param entities the collection to search
* @param entityClass the entity class to look up
* @param entityId the entity id to look up

View file

@ -44,7 +44,8 @@ class CrashControllerTests {
@Test
void testTriggerException() throws Exception {
mockMvc.perform(get("/oups")).andExpect(view().name("exception"))
.andExpect(model().attributeExists("exception"))
.andExpect(forwardedUrl("exception")).andExpect(status().isOk());
.andExpect(model().attributeExists("exception")).andExpect(forwardedUrl("exception"))
.andExpect(status().isOk());
}
}

View file

@ -65,16 +65,14 @@ class VetControllerTests {
@Test
void testShowVetListHtml() throws Exception {
mockMvc.perform(get("/vets.html"))
.andExpect(status().isOk())
.andExpect(model().attributeExists("vets"))
mockMvc.perform(get("/vets.html")).andExpect(status().isOk()).andExpect(model().attributeExists("vets"))
.andExpect(view().name("vets/vetList"));
}
@Test
void testShowResourcesVetList() throws Exception {
ResultActions actions = mockMvc.perform(get("/vets")
.accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
ResultActions actions = mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
actions.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.vetList[0].id").value(1));
}

View file

@ -31,8 +31,7 @@ class VetTests {
vet.setFirstName("Zaphod");
vet.setLastName("Beeblebrox");
vet.setId(123);
Vet other = (Vet) SerializationUtils
.deserialize(SerializationUtils.serialize(vet));
Vet other = (Vet) SerializationUtils.deserialize(SerializationUtils.serialize(vet));
assertThat(other.getFirstName()).isEqualTo(vet.getFirstName());
assertThat(other.getLastName()).isEqualTo(vet.getLastName());
assertThat(other.getId()).isEqualTo(vet.getId());