【问题标题】:What needs to be updated to make the JUnit5 test successful?需要更新哪些内容才能使 JUnit5 测试成功?
【发布时间】:2022-01-23 01:04:09
【问题描述】:

我已经为我在 SNHU 的计算机科学课程创建了这个 Java 项目,并且对为什么在对代码运行 JUnit5 测试时遇到这些错误感到困惑和困惑。我在运行 JUnit5 测试时收到的错误是:

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)

我在 Eclipse 中运行这个项目并且软件是最新的。以下是此作业的说明和代码。提前谢谢你。

说明:

概览

正如您在模块 1 和模块 2 中所了解的那样,可以针对给定情况采用各种类型的软件测试。对于本作业,您将使用代码创建单元测试以发现移动应用程序的错误。您将开发联系服务和联系对象。

提示

对于将在模块六中完成的项目一,您被要求为客户开发一个移动应用程序。客户将向您提供要求。您的工作是编写应用程序代码并提供单元测试以验证应用程序是否满足客户的要求。对于这个里程碑,您将专注于提供联系服务。这些服务的目的是在应用程序中添加、更新和删除联系人对象。

联系人服务使用内存数据结构来支持存储联系人(不需要数据库)。此外,此里程碑没有用户界面。您将通过 JUnit 测试验证联系服务。联系服务包含联系对象以及联系服务。要求概述如下。

联系班级要求

  • 联系人对象应具有要求的唯一联系人 ID 字符串,不能超过 10 个字符。联系人 ID 不得为空且不可更新。
  • 联系人对象应具有一个不能超过 10 个字符的必填名字符串字段。 firstName 字段不得为空。
  • 联系人对象应具有不能超过 10 个字符的必需的姓氏字符串字段。 lastName 字段不得为空。
  • 联系人对象应有一个必需的电话字符串字段,该字段必须正好是 10 位数字。电话字段不得为空。
  • 联系人对象应具有必填的地址字段,该字段不得超过 30 个字符。地址字段不得为空。

联系服务要求

  • 联系人服务应该能够添加具有唯一 ID 的联系人。
  • 联系人服务应该能够删除每个联系人 ID 的联系人。
  • 联系人服务应该能够删除每个联系人 ID 的联系人。
  • 联系人服务应该能够更新每个联系人 ID 的联系人字段。以下字段是可更新的:
  • 名字
  • 姓氏
  • 号码
  • 地址

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"));
}

}

【问题讨论】:

    标签: java unit-testing junit5


    【解决方案1】:

    在检查了你的代码之后,我可以找出这些错误,因为你的测试失败了。

    测试 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.");
    }
    }
    

    失败的原因:

    创建对象联系人时,您没有传递地址值,因为您的构造函数只有这些值:

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

    因此,默认情况下,您的地址值仅为 null。当您对空对象(contact.getAddress().length()) 应用任何方法调用时,它会给出空指针异常。

    测试 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.");
    }
    }
    

    失败的原因:

    您传递的是字符串地址而不是您的电话号码: 你必须纠正你的测试才能通过

    @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.");
    }
    }
    

    另外,如果不是在运行每个测试之前创建一个新对象,您实际上应该使用 @Before annotation 在运行每个测试之前创建初始化条件。

    整改

    @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);
    }
    

    做了这些整改后,所有的测试都通过了

    【讨论】:

    • 您是如何让“联系地址不能超过 30 个字符”无错误通过的?
    • 在你的联系人类中定义一个构造函数来初始化地址
    • @MathewDawson 我已经编辑了答案,并对失败的测试 2 进行了纠正。请看一下
    • @MathewDawson 打印语句是调试的一部分。你可以删除它们
    猜你喜欢
    • 2011-08-04
    • 2021-04-23
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多