Eclipse中JUnit测试构造器报错:需显式定义构造器处理异常
JUnit测试类构造器异常编译错误的解决方法
问题场景
在Eclipse中编写JUnit测试用例时,遇到编译错误:
Default constructor cannot handle exception type InvalidArgException thrown by implicit super constructor. Must define an explicit constructor
涉及的三类代码如下:
ContactTest测试类
package test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import Main.Contact; class ContactTest { Contact contact = new Contact("13579", "Garrett", "Strang", "1234567890", "2468 Washington Avenue"); @Test void getContactID() { assertEquals("13579", contact.getContactID()); } @Test void getFirstname() { assertEquals("Garrett", contact.getFirstName()); } @Test void getLastName() { assertEquals("Strang", contact.getLastName()); } @Test void getPhoneNumber() { assertEquals("1234567890", contact.getPhoneNumber()); } @Test void getAddress() { assertEquals("2468 Washington Avenue", contact.getAddress()); } }
Contact类
package Main; public class Contact { // 声明私有成员变量 private String contactID; private String firstName; private String lastName; private String phoneNum; private String address; // 验证参数合法性 public Contact(String cID, String fN, String lN, String pN, String addr) throws InvalidArgException { // 联系人ID不能为null且长度不超过10 if (cID == null || cID.length() > 10) { throw new InvalidArgException("CONTACT ID IS INVALID"); } if (fN == null || fN.length() > 10) { throw new InvalidArgException("FIRST NAME IS INVALID"); } if (lN == null || lN.length() > 10) { throw new InvalidArgException("LAST NAME IS INVALID"); } if (pN == null || pN.length() != 10) { // 原代码判断>10,改为!=10更符合手机号逻辑 throw new InvalidArgException("PHONE NUMBER IS INVALID"); } if (addr == null || addr.length() > 30) { // 原代码判断>10,地址长度限制调整为30更合理 throw new InvalidArgException("ADDRESS IS INVALID"); } // 原代码遗漏成员变量赋值,必须添加 this.contactID = cID; this.firstName = fN; this.lastName = lN; this.phoneNum = pN; this.address = addr; } // 原代码遗漏getter方法,测试类调用会报错,必须补充 public String getContactID() { return contactID; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public String getPhoneNumber() { return phoneNum; } public String getAddress() { return address; } }
InvalidArgException异常类
package Main; @SuppressWarnings("serial") public class InvalidArgException extends Exception { public InvalidArgException(String string) { super(string); System.out.println(string + " IS AN INVALID ARGUMENT"); } }
错误原因
Contact类的构造器抛出了检查型异常InvalidArgException,而ContactTest类中直接在成员变量位置初始化Contact实例,这段初始化代码会被编译器自动放入测试类的默认构造器中。由于默认构造器没有声明抛出该异常,违反了Java检查型异常的处理规则,因此编译报错。
解决方法
方法一:给测试类添加显式构造器并声明抛出异常
修改ContactTest类,添加构造器并抛出异常:
package test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import Main.Contact; import Main.InvalidArgException; class ContactTest { Contact contact; public ContactTest() throws InvalidArgException { contact = new Contact("13579", "Garrett", "Strang", "1234567890", "2468 Washington Avenue"); } // 测试方法保持不变... }
方法二:使用JUnit的@BeforeEach方法初始化实例(推荐)
将Contact的初始化逻辑移到@BeforeEach注解修饰的方法中,并在方法上声明抛出异常:
package test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import Main.Contact; import Main.InvalidArgException; class ContactTest { Contact contact; @BeforeEach void setUp() throws InvalidArgException { contact = new Contact("13579", "Garrett", "Strang", "1234567890", "2468 Washington Avenue"); } // 测试方法保持不变... }
方法三:将异常改为非检查型异常
修改InvalidArgException继承RuntimeException,这样构造器无需显式声明抛出异常,调用方也无需强制捕获:
package Main; @SuppressWarnings("serial") public class InvalidArgException extends RuntimeException { public InvalidArgException(String string) { super(string); System.out.println(string + " IS AN INVALID ARGUMENT"); } }
此时Contact类的构造器可以去掉throws InvalidArgException声明,测试类的初始化代码也无需处理异常。
额外修复点
Contact类的构造器中遗漏了成员变量的赋值,必须添加赋值语句,否则所有getter方法都会返回null。Contact类中遗漏了getter方法,测试类调用这些方法会编译报错,必须补充。- 原
Contact类中地址长度限制为10字符明显不合理,建议调整为30字符;手机号应该严格限制为10字符(判断pN.length() != 10),而非仅判断长度不超过10。
内容的提问来源于stack exchange,提问作者GiantFlyer1945
相关产品推荐
相关产品推荐

