diff --git a/src/main/java/org/springframework/samples/petclinic/newDataStore/NewOwnerStore.java b/src/main/java/org/springframework/samples/petclinic/newDataStore/NewOwnerStore.java new file mode 100644 index 000000000..3d1264d6e --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/newDataStore/NewOwnerStore.java @@ -0,0 +1,107 @@ +/* + * Software property of Acquisio. Copyright 2003-2018. + */ +package org.springframework.samples.petclinic.newDataStore; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import org.springframework.samples.petclinic.owner.Owner; +import org.springframework.samples.petclinic.owner.OwnerRepository; +import org.springframework.samples.petclinic.owner.StaticOwner; + +/** + * @author Gibran + */ +public class NewOwnerStore { + + private HashMap ownerStore; + private final OwnerRepository owners; + + private static NewOwnerStore storeSingleton; + + private Collection ownerRepositoryData; + + + private NewOwnerStore(OwnerRepository owners) { + this.owners = owners; + this.ownerStore = new HashMap<>(); + } + + public static NewOwnerStore getInstance(OwnerRepository owners) + { + if (storeSingleton == null) + storeSingleton = new NewOwnerStore(owners); + + return storeSingleton; + } + + + + public void forklift() { + Collection ownerRepositoryData = this.owners.findAll(); + for(Owner owner : ownerRepositoryData) { + ownerStore.put(owner.getId(), StaticOwner.convertToStaticOwner(owner)); + } + } + + public HashMap getStore() + { + return ownerStore; + } + + public void findAndReplace(Owner owner) { + boolean exists = false; + + for (StaticOwner o : getStore().values()) { + if (o.getId() == owner.getId()) { + exists = true; + } + } + + // Replace + getStore().put(owner.getId(), StaticOwner.convertToStaticOwner(owner)); + } + + // Report whether inexistent or inconsistent based on exists + + public int checkConsistency() { + int inconsistencies = 0; + + ownerRepositoryData = this.owners.findAll(); + + Iterator iterator = ownerRepositoryData.iterator(); + + for (Integer id: ownerStore.keySet()){ + + if(iterator.hasNext()) { + Owner oldOwner = iterator.next(); + if(id != oldOwner.getId() || !ownerStore.get(id).equals(oldOwner)) { + ownerStore.put(id, StaticOwner.convertToStaticOwner(oldOwner)); + inconsistencies++; + violation(id, StaticOwner.convertToStaticOwner(oldOwner), ownerStore.get(id)); + } + } + } + return inconsistencies; + } + + private void violation(int i, StaticOwner expected, StaticOwner actual) + { + System.out.println("Consistency Violation! \nā€ + ā€œi = ā€ + i + ā€œ\n\t expected = " + + expected.toString() + "\n\t actual = " + actual.toString()); + } + + public void save(Owner owner){ + //actual write to datastore + owners.save(owner); + //shadow write to new datastore + ownerStore.put(owner.getId(), StaticOwner.convertToStaticOwner(owner)); + } + + //this is for testing to introduce inconsistencies + public void testPutInOldDatastoreOnly(Owner owner){ + owners.save(owner); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java index 89aad2c2c..f464b58ba 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java @@ -149,4 +149,7 @@ public class Owner extends Person { .append("firstName", this.getFirstName()).append("address", this.address) .append("city", this.city).append("telephone", this.telephone).toString(); } + + // for testing + public Owner() {} } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java index d914ed745..9ee83eb3a 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -16,6 +16,7 @@ package org.springframework.samples.petclinic.owner; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.newDataStore.NewOwnerStore; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -27,8 +28,11 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.Map; +import java.util.regex.Pattern; /** * @author Juergen Hoeller @@ -38,7 +42,6 @@ import java.util.Map; */ @Controller class OwnerController { - private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; private final OwnerRepository owners; @@ -86,6 +89,7 @@ class OwnerController { // find owners by last name Collection results = this.owners.findByLastName(owner.getLastName()); + if (results.isEmpty()) { // no owners found result.rejectValue("lastName", "notFound", "not found"); @@ -101,6 +105,7 @@ class OwnerController { } } + @GetMapping("/owners/{ownerId}/edit") public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { Owner owner = this.owners.findById(ownerId); @@ -131,5 +136,4 @@ class OwnerController { mav.addObject(this.owners.findById(ownerId)); return mav; } - } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java index 068f5245d..cbac6b18e 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java @@ -21,6 +21,8 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.dao.DataAccessException; /** * Repository class for Owner domain objects All method names are compliant with Spring Data naming @@ -53,6 +55,15 @@ public interface OwnerRepository extends Repository { @Transactional(readOnly = true) Owner findById(@Param("id") Integer id); + /** + * Retrieve all Owners from the data store. + * + * @return a Collection of Owners + */ + @Transactional(readOnly = true) + @Cacheable("owner") + Collection findAll() throws DataAccessException; + /** * Save an {@link Owner} to the data store, either inserting or updating it. * @param owner the {@link Owner} to save diff --git a/src/main/java/org/springframework/samples/petclinic/owner/StaticOwner.java b/src/main/java/org/springframework/samples/petclinic/owner/StaticOwner.java new file mode 100644 index 000000000..2c56080f5 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/owner/StaticOwner.java @@ -0,0 +1,108 @@ +/* + * Software property of Acquisio. Copyright 2003-2018. + */ +package org.springframework.samples.petclinic.owner; + +import java.util.Objects; + +/** + * @author Gibran + */ +public class StaticOwner { + + private String address; + private String city; + private String telephone; + private Integer id; + private String lastName; + private String firstName; + + public StaticOwner(Integer id, String lastName, String firstName, String address, String city, String telephone) + { + this.setId(id); + this.setLastName(lastName); + this.setFirstName(firstName); + this.setAddress(address); + this.setCity(city); + this.setTelephone(telephone); + } + + public StaticOwner(Integer id, String firstName, String lastName) + { + this.setId(id); + this.setLastName(lastName); + this.setFirstName(firstName); + } + + public void setAddress(String address) { + this.address = address; + } + + public void setCity(String city) { + this.city = city; + } + + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + Owner owner = (Owner) o; + + return Objects.equals(address, owner.getAddress()) && + Objects.equals(city, owner.getCity()) && + Objects.equals(telephone, owner.getTelephone()) && + Objects.equals(firstName, owner.getFirstName()) && + Objects.equals(lastName, owner.getLastName()) && + Objects.equals(id, owner.getId()); + } + + @Override + public int hashCode() { + return Objects.hash(address, city, telephone); + } + + public String getAddress () { + return address; + } + + public String getCity() { + return city; + } + + public String getTelephone () { + return telephone; + } + + public static StaticOwner convertToStaticOwner(Owner owner) { + return new StaticOwner(owner.getId(), owner.getLastName(), owner.getFirstName(), + owner.getAddress(), owner.getCity(), owner.getTelephone()); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java index d7afed12e..99915e7c0 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java @@ -34,8 +34,8 @@ import java.util.Map; * @author Dave Syer */ @Controller -class VisitController { - +public class VisitController // Set to public for testing -- can otherwise be accessed with annotations not covered in class +{ private final VisitRepository visits; private final PetRepository pets; diff --git a/src/test/java/org/springframework/samples/petclinic/newDataStore/NewOwnerStoreTest.java b/src/test/java/org/springframework/samples/petclinic/newDataStore/NewOwnerStoreTest.java new file mode 100644 index 000000000..7abe9a6f7 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/newDataStore/NewOwnerStoreTest.java @@ -0,0 +1,153 @@ +/* + * Software property of Acquisio. Copyright 2003-2018. + */ +package org.springframework.samples.petclinic.newDataStore; + + +import java.util.*; +import java.util.regex.Pattern; + +import org.junit.Before; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.samples.petclinic.owner.Owner; +import org.springframework.samples.petclinic.owner.OwnerRepository; +import org.springframework.samples.petclinic.owner.StaticOwner; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.*; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +/** + * @author Gibran + */ +@RunWith(SpringRunner.class) +@DataJpaTest +public class NewOwnerStoreTest { + + private static final int TEST_OWNER_ID = 1; + + @Autowired + OwnerRepository ownerRepository; + + NewOwnerStore testOwnerStore; + + Map ownerStore; + + @Mock + Owner owner; + + @Before + public void setup() { + testOwnerStore = NewOwnerStore.getInstance(ownerRepository); + testOwnerStore.forklift(); + ownerStore = testOwnerStore.getStore(); + /* + MockitoAnnotations.initMocks(this); + when(owner.getId()).thenReturn(TEST_OWNER_ID); + when(owner.getFirstName()).thenReturn("John"); + when(owner.getLastName()).thenReturn("Doe"); + when(owner.getAddress()).thenReturn("123 Cucumber Lane"); + when(owner.getCity()).thenReturn("Placeville"); + when(owner.getTelephone()).thenReturn("1234567890"); + doReturn("Doe").when(owner).getLastName(); + given(this.ownerRepository.findById(TEST_OWNER_ID)).willReturn(owner); + */ + } + + @Test + public void testForklift() { + for (Integer id: ownerStore.keySet()){ + + Integer key = id; + String value = ownerStore.get(id).getAddress(); + System.out.println(key + " " + value); + } + } + + @Test + public void testShadowRead() { + testOwnerStore = NewOwnerStore.getInstance(ownerRepository); + testOwnerStore.forklift(); + + Collection results = this.ownerRepository.findByLastName(""); + + int inconsistencies = compareResults(results, ""); + + assertEquals(inconsistencies, 0); + + // Introduce inconsistency + testOwnerStore.getStore().put(TEST_OWNER_ID, new StaticOwner(TEST_OWNER_ID, "First", "Last")); + inconsistencies = compareResults(results, ""); + assertEquals(inconsistencies, 1); + + + // Inconsistency should be gone + inconsistencies = compareResults(results, ""); + assertEquals(inconsistencies, 0); + } + + private int compareResults(Collection results, String lastName) { + + String pattern = "/^" + lastName + "/"; + + ArrayList staticOwners = new ArrayList<>(); + + for (StaticOwner owner : ownerStore.values()) { + if (!Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(owner.getLastName()).find()) + staticOwners.add(owner); + } + + System.out.println("Size: " + staticOwners.size()); + int inconsistencies = 0; + + for (Owner owner : results) + { + boolean found = false; + for (StaticOwner staticOwner : staticOwners) + { + if (staticOwner.equals(owner)) { + System.out.println("Found. Good"); + found = true; + continue; + } + } + + if (!found) + { + inconsistencies++; + System.out.println("Not Found. Bad"); + testOwnerStore.findAndReplace(owner); + } + + } + + return inconsistencies; + } + + @Test + public void consistencyCheck () { + System.out.println(testOwnerStore.checkConsistency()); + } + + //@Test + public void testShadowWrite() { + testOwnerStore = NewOwnerStore.getInstance(ownerRepository); + + //make sure that inconsistencies are recorded and fixed + testOwnerStore.testPutInOldDatastoreOnly(owner); + assertEquals(1, testOwnerStore.checkConsistency()); + assertEquals(0, testOwnerStore.checkConsistency()); + + //make sure that any changes written to old database are also written to new database + testOwnerStore.save(owner); + assertEquals(0, testOwnerStore.checkConsistency()); + } +} diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index 7fccb3b04..90a7636d6 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -1,26 +1,25 @@ package org.springframework.samples.petclinic.owner; -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.is; -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; - import org.assertj.core.util.Lists; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.samples.petclinic.owner.Owner; -import org.springframework.samples.petclinic.owner.OwnerController; -import org.springframework.samples.petclinic.owner.OwnerRepository; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doReturn; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; /** * Test class for {@link OwnerController} @@ -39,17 +38,18 @@ public class OwnerControllerTests { @MockBean private OwnerRepository owners; + @Mock private Owner george; @Before public void setup() { - george = new Owner(); - george.setId(TEST_OWNER_ID); - george.setFirstName("George"); - george.setLastName("Franklin"); - george.setAddress("110 W. Liberty St."); - george.setCity("Madison"); - george.setTelephone("6085551023"); + MockitoAnnotations.initMocks(this); + doReturn(TEST_OWNER_ID).when(george).getId(); + doReturn("George").when(george).getFirstName(); + doReturn("Franklin").when(george).getLastName(); + doReturn("110 W. Liberty St.").when(george).getAddress(); + doReturn("Madison").when(george).getCity(); + doReturn("6085551023").when(george).getTelephone(); given(this.owners.findById(TEST_OWNER_ID)).willReturn(george); } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java index f95d7c87c..892bbc3f4 100755 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java @@ -1,5 +1,17 @@ package org.springframework.samples.petclinic.owner; +import org.assertj.core.util.Lists; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; import static org.mockito.BDDMockito.given; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -7,25 +19,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; -import org.assertj.core.util.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.FilterType; -import org.springframework.samples.petclinic.owner.Owner; -import org.springframework.samples.petclinic.owner.OwnerRepository; -import org.springframework.samples.petclinic.owner.Pet; -import org.springframework.samples.petclinic.owner.PetController; -import org.springframework.samples.petclinic.owner.PetRepository; -import org.springframework.samples.petclinic.owner.PetType; -import org.springframework.samples.petclinic.owner.PetTypeFormatter; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; - /** * Test class for the {@link PetController} * @@ -51,14 +44,20 @@ public class PetControllerTests { @MockBean private OwnerRepository owners; + @Mock + private Owner owner; + + @Mock + private Pet pet; + @Before public void setup() { PetType cat = new PetType(); cat.setId(3); cat.setName("hamster"); given(this.pets.findPetTypes()).willReturn(Lists.newArrayList(cat)); - given(this.owners.findById(TEST_OWNER_ID)).willReturn(new Owner()); - given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); + given(this.owners.findById(TEST_OWNER_ID)).willReturn(owner); + given(this.pets.findById(TEST_PET_ID)).willReturn(pet); } diff --git a/src/test/java/org/springframework/samples/petclinic/teamkoganM2additions/TestPetTypeFormatter.java b/src/test/java/org/springframework/samples/petclinic/teamkoganM2additions/TestPetTypeFormatter.java new file mode 100644 index 000000000..c75b25714 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/teamkoganM2additions/TestPetTypeFormatter.java @@ -0,0 +1,73 @@ +package org.springframework.samples.petclinic.teamkoganM2additions; + +import org.junit.Test; +import org.springframework.samples.petclinic.owner.PetRepository; +import org.springframework.samples.petclinic.owner.PetType; +import org.springframework.samples.petclinic.owner.PetTypeFormatter; + +import static org.mockito.Mockito.*; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; + +public class TestPetTypeFormatter { + + @Test + public void testPetTypeFormatter() { + + //create the mock PetRepository + PetRepository mockPetRepository = mock(PetRepository.class); + + //create the mock PetType + PetType mockPetType = mock(PetType.class); + + //call the class under test + PetTypeFormatter PTF = new PetTypeFormatter(mockPetRepository); + + //stub the getName() method + when(mockPetType.getName()).thenReturn("Testy"); + + //test the print method + String name = PTF.print(mockPetType, Locale.ENGLISH); + + //check the result is what we expected + assertEquals("Testy", name); + + //verify the getName method was called + verify(mockPetType).getName(); + + //stub the findPetTypes method to return the PetTypes defined below + when(mockPetRepository.findPetTypes()).thenReturn(PetTypes()); + + //try catch block needed for ParseException that can be thrown when testing the parse method + try { + //test the parse method + PetType testPetType = PTF.parse("Pupper", Locale.ENGLISH); + + //verify the getName method was called + verify(mockPetType).getName(); + + //check that the result is what is expected + assertEquals("Pupper", testPetType.getName()); + } catch (ParseException e) { + e.printStackTrace(); + } + } + + //define some pet types + private List PetTypes() { + List petTypes = new ArrayList<>(); + petTypes.add(new PetType() { + { setName("Doggo"); } + }); + petTypes.add(new PetType() { + { setName("Pupper"); } + }); + return petTypes; + } + +} diff --git a/src/test/java/org/springframework/samples/petclinic/teamkoganM2additions/VisitControllerTest.java b/src/test/java/org/springframework/samples/petclinic/teamkoganM2additions/VisitControllerTest.java new file mode 100644 index 000000000..72416c0c2 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/teamkoganM2additions/VisitControllerTest.java @@ -0,0 +1,38 @@ +package org.springframework.samples.petclinic.teamkoganM2additions; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.util.HashMap; + +import org.junit.Test; +import org.springframework.samples.petclinic.owner.Pet; +import org.springframework.samples.petclinic.owner.PetRepository; +import org.springframework.samples.petclinic.owner.VisitController; +import org.springframework.samples.petclinic.visit.Visit; +import org.springframework.samples.petclinic.visit.VisitRepository; + +public class VisitControllerTest +{ + @Test + public void testPetVisitDate() + { + // Define random pet ID + final Integer PET_ID = 7; + Pet pet7 = new Pet(); + + // Mock dependencies + VisitRepository mockVisitRepo = mock(VisitRepository.class); + PetRepository mockPetRepo = mock(PetRepository.class); + VisitController visitController = new VisitController(mockVisitRepo, mockPetRepo); + + // Define mock behaviour + when(mockPetRepo.findById(PET_ID)).thenReturn(pet7); + + // Call method under inspection + Visit visit = visitController.loadPetWithVisit(PET_ID, new HashMap<>()); + + // Confirm that the same visit date was assigned to the pet + assertEquals(visit.getDate(), pet7.getVisits().get(0).getDate()); + } +}