What needs to be updated to make the JUnit5 test successful?

I have created this Java project for my Computer Science course at SNHU and am getting tripped up and confused as to why I am getting these errors when running a JUnit5 test on the code. The errors that I am receiving when running the JUnit5 test are:

org.opentest4j.AssertionFailedError: First name was not null. == > expected: not < null > 
  at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java: 39)
at org.junit.jupiter.api.Assertions.fail(Assertions.java: 134)
at org.junit.jupiter.api.AssertNotNull.failNull(AssertNotNull.java: 47)
at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java: 36)
at org.junit.jupiter.api.Assertions.assertNotNull(Assertions.java: 308)
at module3.ContactTest.testContactFirstNameNotNull(ContactTest.java: 76)
at java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 64)
at java.base / jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 43)
at java.base / java.lang.reflect.Method.invoke(Method.java: 564)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java: 725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java: 60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java: 131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java: 149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java: 140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java: 84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java: 115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java: 105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java: 106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java: 64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java: 45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java: 37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java: 104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java: 98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java: 214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java: 73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java: 210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java: 135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java: 66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java: 151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java: 73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java: 141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java: 137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java: 139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java: 73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java: 138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java: 95)
at java.base / java.util.ArrayList.forEach(ArrayList.java: 1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java: 41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java: 155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java: 73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java: 141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java: 137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java: 139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java: 73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java: 138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java: 95)
at java.base / java.util.ArrayList.forEach(ArrayList.java: 1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java: 41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java: 155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java: 73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java: 141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java: 137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java: 139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java: 73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java: 138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java: 95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java: 35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java: 57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java: 54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java: 107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java: 88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java: 54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java: 67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java: 52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java: 114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java: 95)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java: 91)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java: 60)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java: 98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java: 40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java: 529)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java: 756)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java: 452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java: 210)

I am running this project in Eclipse and is up to date on software. Below are the instructions as well as the code for this assignment. Thank you in advance.

Instructions:

Overview

As you have learned in Modules One and Two, various types of software testing can be employed for a given situation. For this assignment, you will be creating unit tests using code to uncover errors for a mobile application. You will develop the contact service and contact object.

Prompt

For Project One, which is due in Module Six, you are asked to develop a mobile application for a customer. The customer will provide you with the requirements. Your job is to code the application and provide unit tests to verify that the application meets the customer’s requirements. For this milestone, you will focus on delivering the contact services. The purpose of these services is to add, update, and delete contact objects within the application.

The contact service uses in-memory data structures to support storing contacts (no database required). In addition, there is no user interface for this milestone. You will verify the contact service through JUnit tests. The contact service contains a contact object along with the contact service. The requirements are outlined below.

Contact Class Requirements

  • The contact object shall have a required unique contact ID string that cannot be longer than 10 characters. The contact ID shall not be null and shall not be updatable.
  • The contact object shall have a required firstName String field that cannot be longer than 10 characters. The firstName field shall not be null.
  • The contact object shall have a required lastName String field that cannot be longer than 10 characters. The lastName field shall not be null.
  • The contact object shall have a required phone String field that must be exactly 10 digits. The phone field shall not be null.
  • The contact object shall have a required address field that must be no longer than 30 characters. The address field shall not be null.

Contact Service Requirements

  • The contact service shall be able to add contacts with a unique ID.
  • The contact service shall be able to delete contacts per contact ID.
  • The contact service shall be able to delete contacts per contact ID.
  • The contact service shall be able to update contact fields per contact ID. The following fields are updatable:
  • firstName
  • lastName
  • Number
  • Address

Contact.java

//Description: This is the contact class. It creates and stores contact information.

package module3;

public class Contact {
   String contactID;
   String firstName;
   String lastName;
   String phoneNumber;
   String address;
  
   public Contact(String contactID, String firstName, String lastName, String phoneNumber) {
       super();
       this.contactID = contactID;
       this.firstName = firstName;
       this.lastName = lastName;
       this.phoneNumber = phoneNumber;
       this.address = address;
   }
  
   public String getContactID() {
       return contactID;
   }

   public void setContactID(String contactID) {
       this.contactID = contactID;
   }

   public String getFirstName() {
       return firstName;
   }

   public void setFirstName(String firstName) {
       this.firstName = firstName;
   }

   public String getLastName() {
       return lastName;
   }

   public void setLastName(String lastName) {
       this.lastName = lastName;
   }

   public String getPhoneNumber() {
       return phoneNumber;
   }

   public void setPhoneNumber(String phoneNumber) {
       this.phoneNumber = phoneNumber;
   }

   public String getAddress() {
       return address;
   }

   public void setAddress(String address) {
       this.address = address;
   }

   @Override
   public String toString() {
       return "Contact [contactID=" + contactID + ", firstName=" + firstName + ", lastName=" + lastName
               + ", phoneNumber=" + phoneNumber + ", address=" + address + "]";
   }
  
}

ContactService.java:

//Description: This is the contact service. It maintains a list of contacts and has capabilities
//for adding and deleting contacts, as well as updating first name, last name, phone number, and address.

package module3;

import java.util.ArrayList;

public class ContactService {
//will contain our list of contacts
  
private ArrayList<Contact> contacts;
  
public ContactService()
{
//beginning call for the array list
contacts = new ArrayList<>();
}
  
//need to have an add contact, remove contact and update contact feature
//set add contact to have all values
public boolean addContact(Contact contact){
boolean contactAlready= false;
//run through all the contacts in the list made
for (Contact contactList:contacts)
{
//test to see if already a contact
//if so make contactAlready true
if (contactList.equals(contact))
{
contactAlready = true;
}
}
//if not a contact add it as one
if (!contactAlready)
{
contacts.add(contact);
//after adding is now true
return true;
}
else
{
return false;
}
}
  
//delete needed via contactID
public boolean deleteContact(String string)
{
//run through list of contacts
for (Contact contactList:contacts)
{
//if equals to contactID will remove and return
if (contactList.getContactID().equals(string))
{
//remove and return true
contacts.remove(contactList);
return true;
}
}
//else return false
return false;
}
  
//update is trickiest due to needing to make sure still fits parameters
//nothing means no change
public boolean updateContact(String contactID, String firstName, String lastName, String phoneNumber, String address)
{
//run through loop again
for (Contact contactList:contacts)
{
//if contactID matches, run through each with making sure not "" and meets requirements
//then return true as it did equal update.
if (contactList.getContactID().equals(contactID))
{
if(!firstName.equals("") && !(firstName.length()>10))
{
contactList.setFirstName(firstName);
}
if(!lastName.equals("") && !(lastName.length()>10))
{
contactList.setFirstName(lastName);
}
if(!phoneNumber.equals("") && (phoneNumber.length()==10))
{
contactList.setFirstName(phoneNumber);
}
if(!address.equals("") && !(address.length()>30))
{
contactList.setFirstName(address);
}
return true;
}
}
//else return false
return false;
}
}

ContactTest.java:

//Description: This is the unit tests for the contact class (ContactTest).

package module3;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.*;

public class ContactTest {
/*
* The following tests exercise the Contact class.
* The first 5 tests to make sure the field does not become longer than the constraint
* (10 characters for first and last name, exactly 10 characters for phone number,
* and 30 characters for the address).
* The last 4 tests ensure that each field is not null.
* ContactID is not tested for being not null because there isn't a way to create
* a contact with a null contactID. Likewise it is not tested for being non-updateable
* because there is no way to update it.
*/
@Test
@DisplayName("Contact ID cannot have more than 10 characters")
void testContactIDWithMoreThanTenCharacters() {
Contact contact = new Contact("FirstName","LastName","PhoneNumbr","Address");
if(contact.getContactID().length() > 10) {
fail("Contact ID has more than 10 characters.");
}
}

@Test
@DisplayName("Contact First Name cannot have more than 10 characters")
void testContactFirstNameWithMoreThanTenCharacters() {
Contact contact = new Contact("OllyOllyOxenFree","LastName","PhoneNumbr","Address");
if(contact.getFirstName().length() > 10) {
fail("First Name has more than 10 characters.");
}
}

@Test
@DisplayName("Contact Last Name cannot have more than 10 characters")
void testContactLastNameWithMoreThanTenCharacters() {
Contact contact = new Contact("FirstName","OllyOllyOxenFree","PhoneNumbr","Address");
if(contact.getLastName().length() > 10) {
fail("Last Name has more than 10 characters.");
}
}

@Test
@DisplayName("Contact phone number is exactly 10 characters")
void testContactNumberWithMoreThanTenCharacters() {
Contact contact = new Contact("FirstName", "LastName", "55555555555","Address");
if(contact.getPhoneNumber().length() != 10) {
fail("Phone number length does not equal 10.");
}
}

@Test
@DisplayName("Contact address cannot have more than 30 characters")
void testContactAddressWithMoreThanThirtyCharacters() {
Contact contact = new Contact("FirstName","LastName","PhoneNumbr","123456789 is nine characters long"
+ "123456789 is another nine characters long");
if(contact.getAddress().length() > 30) {
fail("Address has more than 30 characters.");
}
}

@Test
@DisplayName("Contact First Name shall not be null")
void testContactFirstNameNotNull() {
Contact contact = new Contact(null, null, null, null);
assertNotNull(contact.getFirstName(), "First name was not null.");
}

@Test
@DisplayName("Contact Last Name shall not be null")
void testContactLastNameNotNull() {
Contact contact = new Contact(null, null, null, null);
assertNotNull(contact.getLastName(), "Last name was null.");
}

@Test
@DisplayName("Contact Phone Number shall not be null")
void testContactPhoneNotNull() {
Contact contact = new Contact("FirstName", "LastName", null,"Address");
assertNotNull(contact.getPhoneNumber(), "Phone number was null.");
}

@Test
@DisplayName("Contact Address shall not be null")
void testContactAddressNotNull() {
Contact contact = new Contact(null, null, null, null);
assertNotNull(contact.getAddress(), "Address was null.");
}
}

ContactServiceTest.java:

//Description: This is the unit tests for the contact service (ContactServiceTest)

package module3;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class ContactServiceTest {

   //need to test add, delete and update
//templates
/*
* Contact("1413252", "Jane", "Doe", "4444444444", "Sample 24 Drive");
Contact("1309403", "Malleus", "Draconia", "2187123404", "Valley of Thorns");
Contact("9752319", "Vil", "Schoenheit", "9215501793", "Land of Proxynee");
*/
  
@Test
public void testAdd()
{
ContactService cs = new ContactService();
Contact test1 = new Contact("1413252", "Jane", "Doe", "4444444444");
assertEquals(true, cs.addContact(test1));
}

@Test
public void testDelete()
{
   ContactService cs = new ContactService();
     
Contact test1 = new Contact("1413252", "Jane", "Doe", "4444444444");
Contact test2 = new Contact("1309403", "Malleus", "Draconia", "2187123404");
Contact test3 = new Contact("9752319", "Vil", "Schoenheit", "9215501793");

cs.addContact(test1);
cs.addContact(test2);
cs.addContact(test3);

assertEquals(true, cs.deleteContact("1309403"));
assertEquals(false, cs.deleteContact("1309404"));
assertEquals(false, cs.deleteContact("1309403"));
}

@Test
public void testUpdate()
{
ContactService cs = new ContactService();
     
Contact test1 = new Contact("1413252", "Jane", "Doe", "4444444444");
Contact test2 = new Contact("1309403", "Malleus", "Draconia", "2187123404");
Contact test3 = new Contact("9752319", "Vil", "Schoenheit", "9215501793");

cs.addContact(test1);
cs.addContact(test2);
cs.addContact(test3);

assertEquals(true, cs.updateContact("9752319", "VilFirst", "SchoenheitLast", "9215501793", "Land of Proxynee"));
assertEquals(false, cs.updateContact("9752322", "VilFirst", "SchoenheitLast", "9215501793", "Land of Proxynee"));
}

}

Solution 1:

After going through you code, these were few mistakes that I could figure out due to which your tests are failing.

TEST 1

@Test
@DisplayName("Contact address cannot have more than 30 characters")
void testContactAddressWithMoreThanThirtyCharacters() {
    
Contact contact = new Contact("FirstName","LastName","PhoneNumbr","123456789 is nine characters long"
+ "123456789 is another nine characters long");
System.out.println("contact address i ---------" + contact.getAddress().length());
if(contact.getAddress().length() > 30) {
fail("Address has more than 30 characters.");
}
}

REASON FOR FAILING :

When creating object contact, you have are not passing value for address as your constructor has only these values :

public Contact(String contactID, String firstName, String lastName, String phoneNumber)

Thus, your address value is by default null only. When you apply any method call on a null object(contact.getAddress().length()) , it gives Null Pointer Exception.

TEST 2

@Test
@DisplayName("Contact phone number is exactly 10 characters")
void testContactNumberWithMoreThanTenCharacters() {
Contact contact = new Contact("FirstName", "LastName", "5555555555","Address");

if(contact.getPhoneNumber().length() != 10) {
fail("Phone number length does not equal 10.");
}
}

REASON FOR FAILING :

You are passing the string address instead of your phone number : You have to rectify your test to pass

@Test
@DisplayName("Contact phone number is exactly 10 characters")
void testContactNumberWithMoreThanTenCharacters() {
Contact contact = new Contact("FirstName", "LastName", "Address","5555555555");
System.out.println("contact digits  i ---------" + contact.getPhoneNumber().length() );
if(contact.getPhoneNumber().length() != 10) {
fail("Phone number length does not equal 10.");
}
}

Also , if instead of creating a new object before running every test, you should actually use @Before annotation to create initialization condition before running each test.

RECTIFICATION:

@Test
@DisplayName("Contact address cannot have more than 30 characters")
void testContactAddressWithMoreThanThirtyCharacters() {
    
Contact c1 = new Contact("FirstName","LastName","value is","PhoneNumbr","address is longer than 30 characters ");
System.out.println("contact address i ---------" + c1.getAddress().length());
System.out.println("contact address i ---------" + c1.getAddress());
System.out.println(c1);
assertTrue(c1.getAddress().length() > 30);
}

After doing these rectifications, all the tests pass enter image description here