-
In a fresh Spring Boot project, there is already a single test class
EventRegistrationApplicationTests
in the src/test/java folder that looks like the following:package ca.mcgill.ecse321.eventregistration; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class EventRegistrationApplicationTests { @Test public void contextLoads() { } }
-
Run this test that checks if the application can successfully load by right clicking on the class → Run as… → JUnit test
ImportantYou need to set the SPRING_DATASOURCE_URL
for the test run configuration as well if you use an environment variable to set datasource URL. See step 5 in section 3.3.1. -
Add a new test class
ca.mcgill.ecse321.eventregistration.service.TestEventRegistrationService
and implement tests for the servicepackage ca.mcgill.ecse321.eventregistration.service; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.sql.Date; import java.sql.Time; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.List; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import ca.mcgill.ecse321.eventregistration.dao.EventRepository; import ca.mcgill.ecse321.eventregistration.dao.PersonRepository; import ca.mcgill.ecse321.eventregistration.dao.RegistrationRepository; import ca.mcgill.ecse321.eventregistration.model.Event; import ca.mcgill.ecse321.eventregistration.model.Person; @RunWith(SpringRunner.class) @SpringBootTest public class TestEventRegistrationService { @Autowired private EventRegistrationService service; @Autowired private PersonRepository personRepository; @Autowired private EventRepository eventRepository; @Autowired private RegistrationRepository registrationRepository; @After public void clearDatabase() { // Fisrt, we clear registrations to avoid exceptions due to inconsistencies registrationRepository.deleteAll(); // Then we can clear the other tables personRepository.deleteAll(); eventRepository.deleteAll(); } @Test public void testCreatePerson() { assertEquals(0, service.getAllPersons().size()); String name = "Oscar"; try { service.createPerson(name); } catch (IllegalArgumentException e) { // Check that no error occurred fail(); } List<Person> allPersons = service.getAllPersons(); assertEquals(1, allPersons.size()); assertEquals(name, allPersons.get(0).getName()); } @Test public void testCreatePersonNull() { assertEquals(0, service.getAllPersons().size()); String name = null; String error = null; try { service.createPerson(name); } catch (IllegalArgumentException e) { error = e.getMessage(); } // check error assertEquals("Person name cannot be empty!", error); // check no change in memory assertEquals(0, service.getAllPersons().size()); } // ... other tests @Test public void testRegisterPersonAndEventDoNotExist() { assertEquals(0, service.getAllRegistrations().size()); String nameP = "Oscar"; Person person = new Person(); person.setName(nameP); assertEquals(0, service.getAllPersons().size()); String nameE = "Soccer Game"; Calendar c = Calendar.getInstance(); c.set(2016, Calendar.OCTOBER, 16, 9, 00, 0); Date eventDate = new Date(c.getTimeInMillis()); Time startTime = new Time(c.getTimeInMillis()); c.set(2016, Calendar.OCTOBER, 16, 10, 30, 0); Time endTime = new Time(c.getTimeInMillis()); Event event = new Event(); event.setName(nameE); event.setDate(eventDate); event.setStartTime(startTime); event.setEndTime(endTime); assertEquals(0, service.getAllEvents().size()); String error = null; try { service.register(person, event); } catch (IllegalArgumentException e) { error = e.getMessage(); } // check error assertEquals("Person does not exist! Event does not exist!", error); // check model in memory assertEquals(0, service.getAllRegistrations().size()); assertEquals(0, service.getAllPersons().size()); assertEquals(0, service.getAllEvents().size()); } // ... other tests }
-
See the complete test suite here.
-
Run the tests and interpret the test error messages! You should see only a few (at least one) tests passing.
-
Update the implementation (i.e., replace the current service method codes with the ones provided below) of the following methods with input validation in the
EventRegistrationService
service class to make the tests pass (Test-Driven Development)@Transactional public Person createPerson(String name) { if (name == null || name.trim().length() == 0) { throw new IllegalArgumentException("Person name cannot be empty!"); } Person person = new Person(); person.setName(name); personRepository.save(person); return person; }
@Transactional public Person getPerson(String name) { if (name == null || name.trim().length() == 0) { throw new IllegalArgumentException("Person name cannot be empty!"); } Person person = personRepository.findPersonByName(name); return person; }
@Transactional public Event getEvent(String name) { if (name == null || name.trim().length() == 0) { throw new IllegalArgumentException("Event name cannot be empty!"); } Event event = eventRepository.findEventByName(name); return event; }
@Transactional public Event createEvent(String name, Date date, Time startTime, Time endTime) { // Input validation String error = ""; if (name == null || name.trim().length() == 0) { error = error + "Event name cannot be empty! "; } if (date == null) { error = error + "Event date cannot be empty! "; } if (startTime == null) { error = error + "Event start time cannot be empty! "; } if (endTime == null) { error = error + "Event end time cannot be empty! "; } if (endTime != null && startTime != null && endTime.before(startTime)) { error = error + "Event end time cannot be before event start time!"; } error = error.trim(); if (error.length() > 0) { throw new IllegalArgumentException(error); } Event event = new Event(); event.setName(name); event.setDate(date); event.setStartTime(startTime); event.setEndTime(endTime); eventRepository.save(event); return event; }
@Transactional public Registration register(Person person, Event event) { String error = ""; if (person == null) { error = error + "Person needs to be selected for registration! "; } else if (!personRepository.existsById(person.getName())) { error = error + "Person does not exist! "; } if (event == null) { error = error + "Event needs to be selected for registration!"; } else if (!eventRepository.existsById(event.getName())) { error = error + "Event does not exist!"; } if (registrationRepository.existsByPersonAndEvent(person, event)) { error = error + "Person is already registered to this event!"; } error = error.trim(); if (error.length() > 0) { throw new IllegalArgumentException(error); } Registration registration = new Registration(); registration.setId(person.getName().hashCode() * event.getName().hashCode()); registration.setPerson(person); registration.setEvent(event); registrationRepository.save(registration); return registration; }
@Transactional public List<Event> getEventsAttendedByPerson(Person person) { if (person == null ) { throw new IllegalArgumentException("Person cannot be null!"); } List<Event> eventsAttendedByPerson = new ArrayList<>(); for (Registration r : registrationRepository.findByPerson(person)) { eventsAttendedByPerson.add(r.getEvent()); } return eventsAttendedByPerson; }
-
Run the tests again, and all should be passing this time.