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
相关产品推荐
相关产品推荐

