JUnit testing for updating object

Viewed 33

I am try to develop a JUnit test for an update method where it updates the contact information based on the ID. But for some reason it keeps failing. I don't know if the problem lies in the ContactService class or the ContactServiceTest file. Can someone help me with this? Here is my code.

Contact.java

package contact;

public class Contact {
    
    // Instance fields
    private String id;
    private String firstName;
    private String lastName;
    private String phone;
    private String address;
    
    public Contact(String id, String firstName, String lastName, String phone, String address) {
        if(id == null || id.length()>10) {
            throw new IllegalArgumentException("Invalid id");
        }
        if(firstName == null || firstName.length()>10) {
            throw new IllegalArgumentException("Invalid first name");
        }
        if(lastName == null || lastName.length()>10) {
            throw new IllegalArgumentException("Invalid last name");
        }
        if(phone == null || phone.length()!=10) {
            throw new IllegalArgumentException("Invalid phone number");
        }
        if(address == null || address.length()>30) {
            throw new IllegalArgumentException("Invalid address");
        }
        
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.phone = phone;
        this.address = address;
    }
    
    public String getId() {
        return id;
    }
    
    // Setter firstName
    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }

    
    public String getFirstName() {
        return firstName;
    }
    
    public String getLastName() {
        return lastName;
    }
    
    public String getPhone() {
        return phone;
    }
    
    public String getAddress() {
        return address;
    }

}

ContactService.java

    package contact;

import java.util.ArrayList;

public class ContactService {

    Contact contact;
    // Can hold multiple contacts
    ArrayList<Contact> contacts = new ArrayList<>();
    
    // Default Constructor
    public ContactService() {
        ArrayList<Contact> contacts = new ArrayList<>();
    }

    // Adds contact to our list if the contact is not present.
    public boolean addNewContact(Contact contact) {
        // Determine if the contact is present.
        boolean isPresent = false;
        for (Contact contactList : contacts) {
            if (contactList.getId().equals(contact.getId())) {
                isPresent = true;
            }
        }
        // If the contact is not present then we add contact, then return true.
        if (!isPresent) {
            contacts.add(contact);
            return true;
        } else {
            return false;
        }
    }

    // If the contact exist in the list, the contact is deleted using contactId
    public boolean deleteExistingContact(String id) {
        for (Contact contactList : contacts) {
            if (contactList.getId().equals(contact.getId())) {
                contacts.remove(contactList);
                return true;

            }
        }
        return false;
    }

    //
    // Update the contact with the given contactId. If the contact is updated in our
    // list then contact will be firstName, lastName, phoneNumber and address.
    public boolean updateExistingContact(String contactID, String firstName, String lastName, String phoneNumber,
            String address) {
        for (Contact contactList : contacts) {
            if (contactList.getId().equals(contact.getId())) {
                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;
            }
        }
        return false;
    }

}

ContactServiceTest.java

    package test;

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

import org.junit.jupiter.api.Test;

import contact.Contact;
import contact.ContactService;

class ContactServiceTest {

    @Test
    void testAdding() {
        ContactService contactservice = new ContactService();
        Contact one = new Contact("123456", "Frodo", "Baggins", "2327148686", "42 Shire Street");
        Contact two = new Contact("343499", "Anakin", "Skywalker", "4534235612", "68 Tatooine Court");
        Contact three = new Contact("585858", "Bart", "Simpson", "6123498999", "42 Shire Street");
        assertEquals(true, contactservice.addNewContact(one));
        assertEquals(true, contactservice.addNewContact(two));
        assertEquals(true, contactservice.addNewContact(three));

    }
    
    @Test
    void testDeleting() {
            ContactService contactservice = new ContactService();
            Contact one = new Contact("123456", "Frodo", "Baggins", "2327148686", "42 Shire Street");
            
            contactservice.deleteExistingContact("123456");
            assertEquals(false, contactservice.deleteExistingContact("123456"));
            
        }
    
    @Test
    void testUpdating() {
        ContactService contactservice = new ContactService();
        
        Contact two = new Contact("343499", "Anakin", "Skywalker", "4534235612", "68 Tatooine Court");
        
        
        contactservice.addNewContact(two);
        
        //Test whether contact info with ID 343499 has been updated, which should be true
        assertEquals(true, contactservice.updateExistingContact("343499", "Luke", "Skywalker", "4534235612", "68 Tatooine Court"));
        //Test whether contact info is false, which it should be because 555888 doesn't exist
        assertEquals(false, contactservice.updateExistingContact("555888", "Luke", "Skywalker", "4534235612", "68 Tatooine Court"));
    }
    

}

Failure Trace

java.lang.NullPointerException: Cannot invoke "contact.Contact.getId()" because "this.contact" is null
at contact.ContactService.updateExistingContact(ContactService.java:52)
at test.ContactServiceTest.testUpdating(ContactServiceTest.java:44)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
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$6(TestMethodTestDescriptor.java:210)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
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:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:84)
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)
1 Answers

The problem is here:

public class ContactService {

    Contact contact;
    // Can hold multiple contacts
    ArrayList<Contact> contacts = new ArrayList<>();

    public ContactService() {
        ArrayList<Contact> contacts = new ArrayList<>();
    }

And here:

public boolean updateExistingContact(String contactID, String firstName, String lastName, String phoneNumber,
        String address) {
    for (Contact contactList : contacts) {
        if (contactList.getId().equals(contact.getId())) {

There's an inconsistency in ContactService class - you assume that it can hold multiple Contact class instances in the contacts list and simultaneously declare field contact holding just one instance of the Contact class. Then, in the updating method in service class, you are comparing ID of contact with IDs of contacts from the list. Also, take a look at the testing method:

    @Test
    void testUpdating() {
        ContactService contactservice = new ContactService();
        
        Contact two = new Contact("343499", "Anakin", "Skywalker", "4534235612", "68 Tatooine Court");
        
        
        contactservice.addNewContact(two);
        
        //Test whether contact info with ID 343499 has been updated, which should be true
        assertEquals(true, contactservice.updateExistingContact("343499", "Luke", "Skywalker", "4534235612", "68 Tatooine Court"));
        //Test whether contact info is false, which it should be because 555888 doesn't exist
        assertEquals(false, contactservice.updateExistingContact("555888", "Luke", "Skywalker", "4534235612", "68 Tatooine Court"));
    }

You are never assigning any value to the contact field, so it is null. Then, you try to call getId() on the null value, which cause that NPE.

Related