diff --git a/pom.xml b/pom.xml
index 9bd5d015..cca65487 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,12 +59,31 @@
${junit-platform.version}
test
+
+ org.junit.jupiter
+ junit-jupiter-params
+ ${junit-platform.version}
+
org.junit.jupiter
junit-jupiter-engine
${junit-platform.version}
test
+
+
+ org.assertj
+ assertj-core
+ 3.11.1
+ test
+
+
+
+ org.hamcrest
+ hamcrest-library
+ 1.3
+ test
+
diff --git a/src/main/java/guru/springframework/sfgpetclinic/controllers/IndexController.java b/src/main/java/guru/springframework/sfgpetclinic/controllers/IndexController.java
index 731a2119..766601a2 100644
--- a/src/main/java/guru/springframework/sfgpetclinic/controllers/IndexController.java
+++ b/src/main/java/guru/springframework/sfgpetclinic/controllers/IndexController.java
@@ -3,11 +3,10 @@
public class IndexController {
public String index(){
-
return "index";
}
- public String oupsHandler(){
- return "notimplemented";
+ public String oopsHandler() {
+ throw new ValueNotFoundException();
}
}
diff --git a/src/main/java/guru/springframework/sfgpetclinic/controllers/ValueNotFoundException.java b/src/main/java/guru/springframework/sfgpetclinic/controllers/ValueNotFoundException.java
new file mode 100644
index 00000000..0f8ad1ad
--- /dev/null
+++ b/src/main/java/guru/springframework/sfgpetclinic/controllers/ValueNotFoundException.java
@@ -0,0 +1,7 @@
+package guru.springframework.sfgpetclinic.controllers;
+
+/**
+ * Created by jt on 2018-10-22.
+ */
+public class ValueNotFoundException extends RuntimeException {
+}
diff --git a/src/main/java/guru/springframework/sfgpetclinic/model/OwnerType.java b/src/main/java/guru/springframework/sfgpetclinic/model/OwnerType.java
new file mode 100644
index 00000000..778cefec
--- /dev/null
+++ b/src/main/java/guru/springframework/sfgpetclinic/model/OwnerType.java
@@ -0,0 +1,9 @@
+package guru.springframework.sfgpetclinic.model;
+
+/**
+ * Created by jt on 2018-10-28.
+ */
+public enum OwnerType {
+
+ INDIVIDUAL, COMPANY
+}
diff --git a/src/main/java/guru/springframework/sfgpetclinic/services/map/VetMapService.java b/src/main/java/guru/springframework/sfgpetclinic/services/map/VetMapService.java
index c94fe453..d04f65c9 100644
--- a/src/main/java/guru/springframework/sfgpetclinic/services/map/VetMapService.java
+++ b/src/main/java/guru/springframework/sfgpetclinic/services/map/VetMapService.java
@@ -28,7 +28,7 @@ public Vet findById(Long id) {
@Override
public Vet save(Vet object) {
- if (object.getSpecialities().size() > 0){
+ if (object.getSpecialities() != null && object.getSpecialities().size() > 0){
object.getSpecialities().forEach(speciality -> {
if(speciality.getId() == null){
Speciality savedSpecialty = specialtyService.save(speciality);
diff --git a/src/test/java/guru/springframework/sfgpetclinic/ControllerTests.java b/src/test/java/guru/springframework/sfgpetclinic/ControllerTests.java
new file mode 100644
index 00000000..952afbb7
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/ControllerTests.java
@@ -0,0 +1,18 @@
+package guru.springframework.sfgpetclinic;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInstance;
+
+/**
+ * Created by jt on 2018-10-28.
+ */
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@Tag("controllers")
+public interface ControllerTests {
+
+ @BeforeAll
+ default void beforeAll(){
+ System.out.println("Lets do something here");
+ }
+}
diff --git a/src/test/java/guru/springframework/sfgpetclinic/CustomArgsProvider.java b/src/test/java/guru/springframework/sfgpetclinic/CustomArgsProvider.java
new file mode 100644
index 00000000..89a5f2da
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/CustomArgsProvider.java
@@ -0,0 +1,20 @@
+package guru.springframework.sfgpetclinic;
+
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+
+import java.util.stream.Stream;
+
+/**
+ * Created by jt on 2018-10-28.
+ */
+public class CustomArgsProvider implements ArgumentsProvider {
+ @Override
+ public Stream extends Arguments> provideArguments(ExtensionContext extensionContext) throws Exception {
+ return Stream.of(
+ Arguments.of("FL", 7, 10),
+ Arguments.of("OH", 11, 42),
+ Arguments.of("MI", 44, 77));
+ }
+}
diff --git a/src/test/java/guru/springframework/sfgpetclinic/ModelRepeatedTests.java b/src/test/java/guru/springframework/sfgpetclinic/ModelRepeatedTests.java
new file mode 100644
index 00000000..615f7815
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/ModelRepeatedTests.java
@@ -0,0 +1,19 @@
+package guru.springframework.sfgpetclinic;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.RepetitionInfo;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+
+/**
+ * Created by jt on 2018-10-28.
+ */
+@Tag("repeated")
+public interface ModelRepeatedTests {
+
+ @BeforeEach
+ default void beforeEachConsoleOutputer(TestInfo testInfo, RepetitionInfo repetitionInfo){
+ System.out.println("Running Test - " + testInfo.getDisplayName() + " - "
+ + repetitionInfo.getCurrentRepetition() + " | " + repetitionInfo.getTotalRepetitions());
+ }
+}
diff --git a/src/test/java/guru/springframework/sfgpetclinic/ModelTests.java b/src/test/java/guru/springframework/sfgpetclinic/ModelTests.java
new file mode 100644
index 00000000..36279857
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/ModelTests.java
@@ -0,0 +1,17 @@
+package guru.springframework.sfgpetclinic;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+
+/**
+ * Created by jt on 2018-10-28.
+ */
+@Tag("model")
+public interface ModelTests {
+
+ @BeforeEach
+ default void beforeEachConsoleOutputer(TestInfo testInfo){
+ System.out.println("Running Test - " + testInfo.getDisplayName());
+ }
+}
diff --git a/src/test/java/guru/springframework/sfgpetclinic/controllers/IndexControllerTest.java b/src/test/java/guru/springframework/sfgpetclinic/controllers/IndexControllerTest.java
new file mode 100644
index 00000000..0756ce83
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/controllers/IndexControllerTest.java
@@ -0,0 +1,108 @@
+package guru.springframework.sfgpetclinic.controllers;
+
+import guru.springframework.sfgpetclinic.ControllerTests;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.*;
+
+import java.time.Duration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+class IndexControllerTest implements ControllerTests {
+
+ IndexController controller;
+
+ @BeforeEach
+ void setUp() {
+ controller = new IndexController();
+ }
+
+ @DisplayName("Test Proper View name is returned for index page")
+ @Test
+ void index() {
+ assertEquals("index", controller.index());
+ assertEquals("index", controller.index(), "Wrong View Returned");
+
+ assertEquals("index", controller.index(), () -> "Another Expensive Message " +
+ "Make me only if you have to");
+
+ assertThat(controller.index()).isEqualTo("index");
+ }
+
+ @Test
+ @DisplayName("Test exception")
+ void oupsHandler() {
+ assertThrows(ValueNotFoundException.class, () -> {
+ controller.oopsHandler();
+ });
+ }
+
+ @Disabled("Demo of timeout")
+ @Test
+ void testTimeOut() {
+
+ assertTimeout(Duration.ofMillis(100), () -> {
+ Thread.sleep(5000);
+
+ System.out.println("I got here");
+ });
+ }
+
+ @Disabled("Demo of timeout")
+ @Test
+ void testTimeOutPrempt() {
+
+ assertTimeoutPreemptively(Duration.ofMillis(100), () -> {
+ Thread.sleep(5000);
+
+ System.out.println("I got here 2342342342342");
+ });
+ }
+
+ @Test
+ void testAssumptionTrue() {
+
+ assumeTrue("GURU".equalsIgnoreCase(System.getenv("GURU_RUNTIME")));
+ }
+
+ @Test
+ void testAssumptionTrueAssumptionIsTrue() {
+
+ assumeTrue("GURU".equalsIgnoreCase("GURU"));
+ }
+
+ @EnabledOnOs(OS.MAC)
+ @Test
+ void testMeOnMacOS() {
+ }
+
+ @EnabledOnOs(OS.WINDOWS)
+ @Test
+ void testMeOnWindows() {
+ }
+
+ @EnabledOnJre(JRE.JAVA_8)
+ @Test
+ void testMeOnJava8() {
+ }
+
+ @EnabledOnJre(JRE.JAVA_11)
+ @Test
+ void testMeOnJava11() {
+ }
+
+ @EnabledIfEnvironmentVariable(named = "USER", matches = "jt")
+ @Test
+ void testIfUserJT() {
+ }
+
+ @EnabledIfEnvironmentVariable(named = "USER", matches = "fred")
+ @Test
+ void testIfUserFred() {
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/guru/springframework/sfgpetclinic/controllers/VetControllerTest.java b/src/test/java/guru/springframework/sfgpetclinic/controllers/VetControllerTest.java
new file mode 100644
index 00000000..7da11f0d
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/controllers/VetControllerTest.java
@@ -0,0 +1,51 @@
+package guru.springframework.sfgpetclinic.controllers;
+
+import guru.springframework.sfgpetclinic.ControllerTests;
+import guru.springframework.sfgpetclinic.fauxspring.Model;
+import guru.springframework.sfgpetclinic.fauxspring.ModelMapImpl;
+import guru.springframework.sfgpetclinic.model.Vet;
+import guru.springframework.sfgpetclinic.services.SpecialtyService;
+import guru.springframework.sfgpetclinic.services.VetService;
+import guru.springframework.sfgpetclinic.services.map.SpecialityMapService;
+import guru.springframework.sfgpetclinic.services.map.VetMapService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class VetControllerTest implements ControllerTests {
+
+ VetService vetService;
+ SpecialtyService specialtyService;
+
+ VetController vetController;
+
+ @BeforeEach
+ void setUp() {
+ specialtyService = new SpecialityMapService();
+ vetService = new VetMapService(specialtyService);
+
+ vetController = new VetController(vetService);
+
+ Vet vet1 = new Vet(1L, "joe", "buck", null);
+ Vet vet2 = new Vet(2L, "Jimmy", "Smith", null);
+
+ vetService.save(vet1);
+ vetService.save(vet2);
+ }
+
+ @Test
+ void listVets() {
+ Model model = new ModelMapImpl();
+
+ String view = vetController.listVets(model);
+
+ assertThat("vets/index").isEqualTo(view);
+
+ Set modelAttribute = (Set) ((ModelMapImpl) model).getMap().get("vets");
+
+ assertThat(modelAttribute.size()).isEqualTo(2);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/guru/springframework/sfgpetclinic/fauxspring/ModelMapImpl.java b/src/test/java/guru/springframework/sfgpetclinic/fauxspring/ModelMapImpl.java
new file mode 100644
index 00000000..9a9d4ad3
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/fauxspring/ModelMapImpl.java
@@ -0,0 +1,26 @@
+package guru.springframework.sfgpetclinic.fauxspring;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by jt on 2018-10-25.
+ */
+public class ModelMapImpl implements Model {
+ Map map = new HashMap<>();
+
+ @Override
+ public void addAttribute(String key, Object o) {
+
+ map.put(key, o);
+ }
+
+ @Override
+ public void addAttribute(Object o) {
+ // do nothing...
+ }
+
+ public Map getMap() {
+ return map;
+ }
+}
diff --git a/src/test/java/guru/springframework/sfgpetclinic/junitextensions/TimingExtension.java b/src/test/java/guru/springframework/sfgpetclinic/junitextensions/TimingExtension.java
new file mode 100644
index 00000000..477319d2
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/junitextensions/TimingExtension.java
@@ -0,0 +1,38 @@
+package guru.springframework.sfgpetclinic.junitextensions;
+
+import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
+import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+import java.lang.reflect.Method;
+import java.util.logging.Logger;
+
+/**
+ * Original source - https://junit.org/junit5/docs/current/user-guide/#extensions-lifecycle-callbacks-timing-extension
+ *
+ * Created by jt on 2018-10-28.
+ */
+public class TimingExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {
+
+ private static final Logger logger = Logger.getLogger(TimingExtension.class.getName());
+
+ private static final String START_TIME = "start time";
+
+ @Override
+ public void beforeTestExecution(ExtensionContext context) throws Exception {
+ getStore(context).put(START_TIME, System.currentTimeMillis());
+ }
+
+ @Override
+ public void afterTestExecution(ExtensionContext context) throws Exception {
+ Method testMethod = context.getRequiredTestMethod();
+ long startTime = getStore(context).remove(START_TIME, long.class);
+ long duration = System.currentTimeMillis() - startTime;
+
+ logger.info(() -> String.format("Method [%s] took %s ms.", testMethod.getName(), duration));
+ }
+
+ private ExtensionContext.Store getStore(ExtensionContext context) {
+ return context.getStore(ExtensionContext.Namespace.create(getClass(), context.getRequiredTestMethod()));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/guru/springframework/sfgpetclinic/model/OwnerTest.java b/src/test/java/guru/springframework/sfgpetclinic/model/OwnerTest.java
new file mode 100644
index 00000000..91aa58d8
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/model/OwnerTest.java
@@ -0,0 +1,91 @@
+package guru.springframework.sfgpetclinic.model;
+
+import guru.springframework.sfgpetclinic.CustomArgsProvider;
+import guru.springframework.sfgpetclinic.ModelTests;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.*;
+
+import java.util.stream.Stream;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class OwnerTest implements ModelTests {
+
+ @Test
+ void dependentAssertions() {
+
+ Owner owner = new Owner(1l, "Joe", "Buck");
+ owner.setCity("Key West");
+ owner.setTelephone("1231231234");
+
+ assertAll("Properties Test",
+ () -> assertAll("Person Properties",
+ () -> assertEquals("Joe", owner.getFirstName(), "First Name Did not Match"),
+ () -> assertEquals("Buck", owner.getLastName())),
+ () -> assertAll("Owner Properties",
+ () -> assertEquals("Key West", owner.getCity(), "City Did Not Match"),
+ () -> assertEquals("1231231234", owner.getTelephone())
+ ));
+
+ assertThat(owner.getCity(), is("Key West"));
+ }
+
+ @DisplayName("Value Source Test")
+ @ParameterizedTest(name = "{displayName} - [{index}] {arguments}")
+ @ValueSource(strings = {"Spring", "Framework", "Guru"})
+ void testValueSource(String val) {
+ System.out.println(val);
+ }
+
+ @DisplayName("Enum Source Test")
+ @ParameterizedTest(name = "{displayName} - [{index}] {arguments}")
+ @EnumSource(OwnerType.class)
+ void enumTest(OwnerType ownerType) {
+ System.out.println(ownerType);
+ }
+
+ @DisplayName("CSV Input Test")
+ @ParameterizedTest(name = "{displayName} - [{index}] {arguments}")
+ @CsvSource({
+ "FL, 1, 1",
+ "OH, 2, 2",
+ "MI, 3, 1"
+ })
+ void csvInputTest(String stateName, int val1, int val2) {
+ System.out.println(stateName + " = " + val1 + ":" + val2);
+ }
+
+ @DisplayName("CSV From File Test")
+ @ParameterizedTest(name = "{displayName} - [{index}] {arguments}")
+ @CsvFileSource(resources = "/input.csv", numLinesToSkip = 1)
+ void csvFromFileTest(String stateName, int val1, int val2) {
+ System.out.println(stateName + " = " + val1 + ":" + val2);
+ }
+
+ @DisplayName("Method Provider Test")
+ @ParameterizedTest(name = "{displayName} - [{index}] {arguments}")
+ @MethodSource("getargs")
+ void fromMethodTest(String stateName, int val1, int val2) {
+ System.out.println(stateName + " = " + val1 + ":" + val2);
+ }
+
+ static Stream getargs() {
+ return Stream.of(
+ Arguments.of("FL", 5, 1),
+ Arguments.of("OH", 2, 8),
+ Arguments.of("MI", 3, 5));
+ }
+
+ @DisplayName("Custom Provider Test")
+ @ParameterizedTest(name = "{displayName} - [{index}] {arguments}")
+ @ArgumentsSource(CustomArgsProvider.class)
+ void fromCustomProviderTest(String stateName, int val1, int val2) {
+ System.out.println(stateName + " = " + val1 + ":" + val2);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/guru/springframework/sfgpetclinic/model/PersonRepeatedTests.java b/src/test/java/guru/springframework/sfgpetclinic/model/PersonRepeatedTests.java
new file mode 100644
index 00000000..d77a3fbc
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/model/PersonRepeatedTests.java
@@ -0,0 +1,31 @@
+package guru.springframework.sfgpetclinic.model;
+
+import guru.springframework.sfgpetclinic.ModelRepeatedTests;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.RepeatedTest;
+import org.junit.jupiter.api.RepetitionInfo;
+import org.junit.jupiter.api.TestInfo;
+
+/**
+ * Created by jt on 2018-10-28.
+ */
+public class PersonRepeatedTests implements ModelRepeatedTests {
+
+ @RepeatedTest(value = 10, name = "{displayName} : {currentRepetition} - {totalRepetitions}")
+ @DisplayName("My Repeated Test")
+ void myRepeatedTest() {
+ //todo - impl
+ }
+
+ @RepeatedTest(5)
+ void myRepeatedTestWithDI(TestInfo testInfo, RepetitionInfo repetitionInfo) {
+ System.out.println(testInfo.getDisplayName() + ": " + repetitionInfo.getCurrentRepetition());
+
+ }
+
+ @RepeatedTest(value = 5, name = "{displayName} : {currentRepetition} | {totalRepetitions}")
+ @DisplayName("My Assignment Repeated Test")
+ void myAssignmentRepeated() {
+ //todo impl
+ }
+}
diff --git a/src/test/java/guru/springframework/sfgpetclinic/model/PersonTest.java b/src/test/java/guru/springframework/sfgpetclinic/model/PersonTest.java
new file mode 100644
index 00000000..a232c91f
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/model/PersonTest.java
@@ -0,0 +1,32 @@
+package guru.springframework.sfgpetclinic.model;
+
+import guru.springframework.sfgpetclinic.ModelTests;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class PersonTest implements ModelTests {
+
+ @Test
+ void groupedAssertions() {
+ //given
+ Person person = new Person(1l, "Joe", "Buck");
+
+ //then
+ assertAll("Test Props Set",
+ () -> assertEquals(person.getFirstName(), "Joe"),
+ () -> assertEquals(person.getLastName(), "Buck"));
+ }
+
+ @Test
+ void groupedAssertionMsgs() {
+ //given
+ Person person = new Person(1l, "Joe", "Buck");
+
+ //then
+ assertAll("Test Props Set",
+ () -> assertEquals(person.getFirstName(), "Joe", "First Name Failed"),
+ () -> assertEquals(person.getLastName(), "Buck", "Last Name Failed"));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/guru/springframework/sfgpetclinic/services/map/OwnerMapServiceTest.java b/src/test/java/guru/springframework/sfgpetclinic/services/map/OwnerMapServiceTest.java
new file mode 100644
index 00000000..f9e99a4f
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/services/map/OwnerMapServiceTest.java
@@ -0,0 +1,107 @@
+package guru.springframework.sfgpetclinic.services.map;
+
+import guru.springframework.sfgpetclinic.model.Owner;
+import guru.springframework.sfgpetclinic.model.PetType;
+import guru.springframework.sfgpetclinic.services.PetService;
+import guru.springframework.sfgpetclinic.services.PetTypeService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("Owner Map Service Test - ")
+class OwnerMapServiceTest {
+
+ OwnerMapService ownerMapService;
+ PetTypeService petTypeService;
+ PetService petService;
+
+ @BeforeEach
+ void setUp() {
+ petTypeService = new PetTypeMapService();
+ petService = new PetMapService();
+ ownerMapService = new OwnerMapService(petTypeService, petService);
+ }
+
+ @DisplayName("Verify Zero Owners")
+ @Test
+ void ownersAreZero() {
+ int ownerCount = ownerMapService.findAll().size();
+
+ assertThat(ownerCount).isZero();
+ }
+
+ @DisplayName("Pet Type - ")
+ @Nested
+ class TestCreatePetTypes {
+
+ @BeforeEach
+ void setUp() {
+ PetType petType = new PetType(1L, "Dog");
+ PetType petType2 = new PetType(2L, "Cat");
+ petTypeService.save(petType);
+ petTypeService.save(petType2);
+ }
+
+ @DisplayName("Test Pet Count")
+ @Test
+ void testPetCount() {
+ int petTypeCount = petTypeService.findAll().size();
+
+ assertThat(petTypeCount).isNotZero().isEqualTo(2);
+ }
+
+ @DisplayName("Save Owners Tests - ")
+ @Nested
+ class SaveOwnersTests {
+
+ @BeforeEach
+ void setUp() {
+ ownerMapService.save(new Owner(1L, "Before", "Each"));
+ }
+
+ @DisplayName("Save Owner")
+ @Test
+ void saveOwner() {
+ Owner owner = new Owner(2L, "Joe", "Buck");
+
+ Owner savedOwner = ownerMapService.save(owner);
+
+ assertThat(savedOwner).isNotNull();
+ }
+
+ @DisplayName("Save Owners Tests - ")
+ @Nested
+ class FindOwnersTests {
+
+ @DisplayName("Find Owner")
+ @Test
+ void findOwner() {
+
+ Owner foundOwner = ownerMapService.findById(1L);
+
+ assertThat(foundOwner).isNotNull();
+ }
+
+ @DisplayName("Find Owner Not Found")
+ @Test
+ void findOwnerNotFound() {
+
+ Owner foundOwner = ownerMapService.findById(2L);
+
+ assertThat(foundOwner).isNull();
+ }
+ }
+ }
+ }
+
+ @DisplayName("Verify Still Zero Owners")
+ @Test
+ void ownersAreStillZero() {
+ int ownerCount = ownerMapService.findAll().size();
+
+ assertThat(ownerCount).isZero();
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/guru/springframework/sfgpetclinic/services/springdatajpa/OwnerSDJpaServiceTest.java b/src/test/java/guru/springframework/sfgpetclinic/services/springdatajpa/OwnerSDJpaServiceTest.java
new file mode 100644
index 00000000..b7b26f9c
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/services/springdatajpa/OwnerSDJpaServiceTest.java
@@ -0,0 +1,48 @@
+package guru.springframework.sfgpetclinic.services.springdatajpa;
+
+import guru.springframework.sfgpetclinic.model.Owner;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+@Disabled(value = "Disabled until we learn Mocking")
+class OwnerSDJpaServiceTest {
+
+ OwnerSDJpaService service;
+
+ @BeforeEach
+ void setUp() {
+ service = new OwnerSDJpaService(null, null, null);
+
+ }
+
+ @Disabled
+ @Test
+ void findByLastName() {
+ Owner foundOwner = service.findByLastName("Buck");
+ }
+
+ @Test
+ void findAllByLastNameLike() {
+ }
+
+ @Test
+ void findAll() {
+ }
+
+ @Test
+ void findById() {
+ }
+
+ @Test
+ void save() {
+ }
+
+ @Test
+ void delete() {
+ }
+
+ @Test
+ void deleteById() {
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/guru/springframework/sfgpetclinic/services/springdatajpa/PetTypeSDJpaServiceIT.java b/src/test/java/guru/springframework/sfgpetclinic/services/springdatajpa/PetTypeSDJpaServiceIT.java
new file mode 100644
index 00000000..36237e6d
--- /dev/null
+++ b/src/test/java/guru/springframework/sfgpetclinic/services/springdatajpa/PetTypeSDJpaServiceIT.java
@@ -0,0 +1,34 @@
+package guru.springframework.sfgpetclinic.services.springdatajpa;
+
+import guru.springframework.sfgpetclinic.junitextensions.TimingExtension;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(TimingExtension.class)
+class PetTypeSDJpaServiceIT {
+
+ @BeforeEach
+ void setUp() {
+ }
+
+ @Test
+ void findAll() {
+ }
+
+ @Test
+ void findById() {
+ }
+
+ @Test
+ void save() {
+ }
+
+ @Test
+ void delete() {
+ }
+
+ @Test
+ void deleteById() {
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/input.csv b/src/test/resources/input.csv
new file mode 100644
index 00000000..2cb9d4ef
--- /dev/null
+++ b/src/test/resources/input.csv
@@ -0,0 +1,4 @@
+state, val1, val2
+FL, 3, 3
+OH, 4, 5
+MI, 8, 3
\ No newline at end of file