Description
Describe the bug
I am new to Quarkus and want to hand on effective java test.
When I used the parameterization test on the ItemWait class by quarkus-junit5:3.9.3, relied XStream library reported an error as below. how can I do, can I replace Xstream? Note that I donnot want to replace the record Class with a regular class Class for ItemDetail.
Version and Build tool
quarkus 3.9.3
maven auto controlled by quarkus
Error Message
com.thoughtworks.xstream.converters.ConversionException:
---- Debugging information ----
cause-exception : java.lang.UnsupportedOperationException
cause-message : can't get field offset on a record class: private final java.lang.String org.todo.domain.item.ItemDetail.name
class : org.todo.domain.item.ItemDetail
required-type : org.todo.domain.item.ItemDetail
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path : /org.todo.domain.item.ItemWait/detail/name
line number : 6
class[1] : org.todo.domain.item.ItemWait
required-type[1] : org.todo.domain.item.ItemWait
version : 1.4.20
Code
@QuarkusTest
class ItemWaitTest {
@Test
void shouldOfWork() {
ItemDetail detail = new ItemDetail("todo1", "content", LocalDateTime.now(), LocalDateTime.now().plusDays(1));
ItemWait wait = ItemWait.of("publisher", "performer", detail);
assertThat(wait.getId()).isNull();
assertThat(wait.getStatus()).isEqualTo(ItemWaitingStatus.WAIT_FOR_RECEPTION);
}
/*
* 测试等效主键与主键,等效主键必须与主键保持一对一关系
* 等效主键是publisher,performer,detail.name的复合,注意这三个值不可以为null
* 主键是id,id可能为null,这是因为可能还没持久化到数据库中
*/
@ParameterizedTest
@MethodSource("equalsTestCases")
void shouldEqualsWork(ItemWait wait1, ItemWait wait2, boolean expected) {
assertThat(wait1.equals(wait2)).isEqualTo(expected);
}
@ParameterizedTest
@MethodSource("equalsTestCasesAssertion")
void shouldEqualsAssert(ItemWait wait1, ItemWait wait2,String errorMessage){
boolean asserted = false;
try{
wait1.equals(wait2);
}catch(AssertionError e){
asserted = true;
assertThat(e.getMessage()).isEqualTo(errorMessage);
}
assertTrue(asserted);
}
static Stream<Arguments> equalsTestCases() {
return Stream.of(
of(wait("a", "b", "c", null),
wait("a", "b", "c", null),
true),
of(wait("x", "b", "c", null),
wait("a", "b", "c", null),
false),
of(wait("a", "x", "c", null),
wait("a", "b", "c", null),
false),
of(wait("a", "b", "x", null),
wait("a", "b", "c", null),
false),
of(wait("x", "y", "c", null),
wait("a", "b", "c", null),
false),
of(wait("x", "b", "y", null),
wait("a", "b", "c", null),
false),
of(wait("a", "x", "y", null),
wait("a", "b", "c", null),
false),
of(wait("x", "y", "z", null),
wait("a", "b", "c", null),
false),
of(wait("a", "b", "c", 1L),
wait("a", "b", "c", null),
true),
of(wait("x", "b", "c", 1L),
wait("a", "b", "c", null),
false),
of(wait("a", "x", "c", 1L),
wait("a", "b", "c", null),
false),
of(wait("a", "b", "x", 1L),
wait("a", "b", "c", null),
false),
of(wait("x", "y", "c", 1L),
wait("a", "b", "c", null),
false),
of(wait("x", "b", "y", 1L),
wait("a", "b", "c", null),
false),
of(wait("a", "x", "y", 1L),
wait("a", "b", "c", null),
false),
of(wait("x", "y", "z", 1L),
wait("a", "b", "c", null),
false),
//等效主键判断与主键判断一致
of(wait("a", "b", "c", 1L),
wait("a", "b", "c", 1L),
true),
of(wait("x", "b", "c", 2L),
wait("a", "b", "c", 1L),
false),
of(wait("a", "x", "c", 2L),
wait("a", "b", "c", 1L),
false),
of(wait("a", "b", "x", 2L),
wait("a", "b", "c", 1L),
false),
of(wait("x", "y", "c", 2L),
wait("a", "b", "c", 1L),
false),
of(wait("x", "b", "y", 2L),
wait("a", "b", "c", 1L),
false),
of(wait("a", "x", "y", 2L),
wait("a", "b", "c", 1L),
false),
of(wait("x", "y", "z", 2L),
wait("a", "b", "c", 1L),
false)
);
}
static Stream<Arguments> equalsTestCasesAssertion() {
String error = "ItemWait的主键与虚拟等效主键不一致";
return Stream.of(
of(wait("a", "b", "c", 2L),
wait("a", "b", "c", 1L),
error),
of(wait("x", "b", "c", 1L),
wait("a", "b", "c", 1L),
error),
of(wait("a", "x", "c", 1L),
wait("a", "b", "c", 1L),
error),
of(wait("a", "b", "x", 1L),
wait("a", "b", "c", 1L),
error),
of(wait("x", "y", "c", 1L),
wait("a", "b", "c", 1L),
error),
of(wait("x", "b", "y", 1L),
wait("a", "b", "c", 1L),
error),
of(wait("a", "x", "y", 1L),
wait("a", "b", "c", 1L),
error),
of(wait("x", "y", "z", 1L),
wait("a", "b", "c", 1L),
error)
);
}
// Simplify the creation of ItemWait for parameterized testing of the equals method
static ItemWait wait(String publisher, String performer, String name, Long id) {
var begin = LocalDateTime.of(2099, 12, 1, 10, 10, 0);
var end = LocalDateTime.of(2099, 12, 2, 10, 10, 0);
var content = "content";
var wait = ItemWait.of(publisher, performer, new ItemDetail(name, content, begin, end));
try {
Field idField = ItemWait.class.getDeclaredField("id");
idField.setAccessible(true);
idField.set(wait, id);
} catch (Exception e) {
e.printStackTrace();
}
return wait;
}
@Test
void shouldWaitInThisFileWork(){
ItemWait wait = wait("a","b","c",1L);
var begin = LocalDateTime.of(2099, 12, 1, 10, 10, 0);
var end = LocalDateTime.of(2099, 12, 2, 10, 10, 0);
assertEquals(1L, wait.getId());
assertEquals("a", wait.getPublisher());
assertEquals("b", wait.getPerformer());
assertEquals("c", wait.getDetail().name());
assertEquals("content", wait.getDetail().content());
assertEquals(wait.getDetail().begin(), begin);
assertEquals(wait.getDetail().end(), end);
}
}
@Entity
public class ItemWait {
@Id
@GeneratedValue
private Long id;
@NotBlank(message = "事项发布者的名称不可以为空")
private String publisher;
@NotBlank(message = "事项执行者的名称不可以为空")
private String performer;
@Embedded
@NotNull(message = "事项详细内容不可以为Null")
private ItemDetail detail;
private ItemWaitingStatus status;
public static ItemWait of(@NotBlank String publisher, @NotBlank String performer, @Valid ItemDetail detail) {
return new ItemWait(null, publisher, performer, detail, ItemWaitingStatus.WAIT_FOR_RECEPTION);
}
private ItemWait(Long id, String publisher, String performer, ItemDetail detail, ItemWaitingStatus status) {
this.id = id;
this.publisher = publisher;
this.performer = performer;
this.detail = detail;
this.status = status;
}
//omit other methods
}
@Embeddable
public record ItemDetail(@NotBlank(message = "事项名称不可以为空") String name,
@NotBlank(message = "事项内容不可以为空") String content,
@NotNull(message = "事项起始时间不可以为NULL") LocalDateTime begin,
@NotNull(message = "事项结束时间不可以为Null") LocalDateTime end) {
public ItemDetail {
LocalDateTime rightBoundary = LocalDateTime.now();
LocalDateTime leftBoundary = rightBoundary.minusSeconds(20);
assert begin.isAfter(leftBoundary) : "无效的事项起始时间";
assert begin.isBefore(end) : "事项起始时间必须在结束时间之前";
}
}
Metadata
Metadata
Assignees
Type
Projects
Status