You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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声明,测试类的初始化代码也无需处理异常。

额外修复点

  1. Contact类的构造器中遗漏了成员变量的赋值,必须添加赋值语句,否则所有getter方法都会返回null。
  2. Contact类中遗漏了getter方法,测试类调用这些方法会编译报错,必须补充。
  3. 原Contact类中地址长度限制为10字符明显不合理,建议调整为30字符;手机号应该严格限制为10字符(判断pN.length() != 10),而非仅判断长度不超过10。

内容的提问来源于stack exchange,提问作者GiantFlyer1945

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:54:21