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

Spring Boot JUnit测试中Point类型实例化错误的修复方案咨询

解决JUnit测试中JTS Point类型的InstantiationError问题

问题背景

在Spring Boot项目的JUnit测试中使用了org.locationtech.jts.geom.Point类型,编写完测试代码后,调用AssignmentEntityBuilder.generateValidUserEntities()方法时触发报错:java.lang.InstantiationError: org.locationtech.jts.geom.CoordinateSequence。

相关代码片段

AssignmentEntity.java

...
public class AssignmentEntity extends BaseEntity {

    ...
    
    public void setPoint(double latitude, double longitude) {
        Coordinate coordinate = new Coordinate(latitude, longitude);
        GeometryFactory geometryFactory = new GeometryFactory();
        this.point = geometryFactory.createPoint(coordinate);
    }

}

AssignmentEntityBuilder.java

public class AssignmentEntityBuilder extends TestDataBuilder<AssignmentEntity> {

    public AssignmentEntityBuilder() {
        super(AssignmentEntity.class);
    }

    public static List<AssignmentEntity> generateValidUserEntities(int size) {
        List<AssignmentEntity> userEntities = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            AssignmentEntity assignmentEntity = new AssignmentEntityBuilder().withValidFields().build();
            userEntities.add(assignmentEntity);
        }
        return userEntities;
    }

    public AssignmentEntityBuilder withValidFields() {
        InstitutionEntity institutionEntity = new InstitutionEntityBuilder().withValidFields().build();

        double x = Math.random();
        double y = Math.random();
        Point point = new GeometryFactory().createPoint(new Coordinate(x, y));

        return this
                .withId(AysRandomUtil.generateUUID())
                .withInstitutionId(institutionEntity.getId())
                .withInstitution(institutionEntity)
                .withPhoneNumber(new AysPhoneNumberBuilder().withValidFields().build())
                .withDescription("Description")
                .withFirstName("First Name")
                .withLastName("Last Name")
                .withStatus(AssignmentStatus.AVAILABLE)
                .withPoint(point);
    }

    // 其余Builder方法省略
}

测试类代码

class AssignmentSaveServiceImplTest extends AbstractUnitTest {

    @InjectMocks
    private AssignmentSaveServiceImpl assignmentSaveService;

    @Mock
    private AssignmentRepository assignmentRepository;

    @Mock
    private AysIdentity identity;

    @Test
    void givenValidAssignmentSaveRequest_whenAssignmentSaved_thenReturnAssignment() {

        // Given
        AssignmentSaveRequest mockAssignmentSaveRequest = new AssignmentSaveRequestBuilder()
                .withValidFields()
                .build();

        List<AssignmentEntity> assignmentsFromDatabase = AssignmentEntityBuilder.generateValidUserEntities(10);  // 错误行

        // 其余测试代码省略
    }
}

核心报错栈

org.jeasy.random.ObjectCreationException: Unable to create a random instance of type class com.ays.assignment.model.entity.AssignmentEntity
    ...
Caused by: java.lang.InstantiationError: org.locationtech.jts.geom.CoordinateSequence
    ...

报错原因分析

InstantiationError通常由以下原因导致:

  • JTS依赖缺失/冲突:CoordinateSequence是接口,无法直接实例化。若测试环境中缺少JTS核心依赖(jts-core),或存在版本冲突,JVM会找不到该接口的实现类。
  • EasyRandom自动生成冲突:你使用的TestDataBuilder基于jeasy-random,它会尝试自动生成所有字段的随机实例,包括Point类型。当它创建Point时,内部需要实例化CoordinateSequence,但因依赖问题或配置缺失触发报错。

修复方案

1. 确保JTS依赖完整且版本统一

检查项目的依赖管理文件(pom.xml或build.gradle),引入正确的JTS核心依赖,并排查版本冲突。

Maven示例

<dependency>
    <groupId>org.locationtech.jts</groupId>
    <artifactId>jts-core</artifactId>
    <version>1.18.2</version> <!-- 使用与项目兼容的稳定版本 -->
</dependency>

Gradle示例

implementation 'org.locationtech.jts:jts-core:1.18.2'

执行依赖树检查命令排查冲突:

  • Maven:mvn dependency:tree
  • Gradle:./gradlew dependencies

若发现冲突,用<exclusions>(Maven)或exclude(Gradle)排除重复/不兼容版本。

2. 禁止EasyRandom自动生成Point字段

由于你已经在withValidFields()中显式创建并设置了Point,无需让EasyRandom自动生成该字段。修改AssignmentEntityBuilder构造方法添加排除配置:

public AssignmentEntityBuilder() {
    super(AssignmentEntity.class);
    // 告诉EasyRandom不要自动生成point字段
    getEasyRandomParameters().excludeFieldByName("point");
}

如果父类TestDataBuilder未暴露getEasyRandomParameters(),可在父类添加该方法,或确保point字段被优先赋值以覆盖自动生成逻辑。

3. 优化Point创建逻辑(可选)

复用GeometryFactory实例提升性能,同时保持创建逻辑的正确性:

// 在Builder类中定义全局GeometryFactory实例
private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();

public AssignmentEntityBuilder withValidFields() {
    // ...其他代码
    Point point = GEOMETRY_FACTORY.createPoint(new Coordinate(Math.random(), Math.random()));
    // ...其他代码
}

验证方法

修改完成后重新运行JUnit测试,若报错消失则说明修复生效。

内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:12:03