1

我的应用程序中有一个 Book 模型类,如下所示:

@Entity
public class Book extends PanacheEntity{
    public String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

在我的测试类中,我创建了这个类的一个实例并调用了 persistAndFlush()。接下来,我放心地对控制器进行 HTTP 调用。我将新创建和持久化实体的 id 作为路径参数传递给控制器​​。

@QuarkusTest
public class GreetingResourceTest {

    @Test
    @Transactional
    public void testBookEndpoint() {
        Book book= new Book();
        book.title="Quarkus is awesome";
        book.persistAndFlush();
        assertTrue(book.isPersistent());
        given()
          .when().get("/hello/"+book.id)
          .then()
             .statusCode(200)
             .body(is("Quarkus is awesome"));
    }
}

控制器成功获取请求。它接收书籍和 id。但是:当控制器查询数据库时,实体不存在。

完整代码如下:

@Path("/hello")
public class GreetingResource {

    @GET
    @Path("/{id}")
    @Produces(MediaType.TEXT_PLAIN)
    public String getBook(@PathParam("id") Long id) {
        Book book=Book.findById(id);
        return book.title; //NullPointerException. Book cannot be found
    }
}

Book.findById(id)返回空值。为什么?

4

1 回答 1

1

这个问题是由所涉及的事务的可见性引起的。尽管调用了,但尚未提交book.persistAndFlush()事务包装。public void testBookEndpoint()因此,新书对 中的事务尚不可见public String getBook(@PathParam("id") Long id)

您需要确保在测试其余端点之前提交插入图书的事务,以确保新图书在数据库中对正在检索它的其余调用可见,例如

@QuarkusTest
public class GreetingResourceTest {
    static Book book;

    @BeforeAll
    @Transactional
    public static void setupEntities(){
        book = new Book();
        book.title="Quarkus is awesome";
        book.persistAndFlush();
        assertTrue(book.isPersistent());
    }

    @Test
    public void testBookEndpoint() {
        given()
                .when().get("/hello/"+book.id)
                .then()
                .statusCode(200)
                .body(is("Quarkus is awesome"));
    }
}
于 2020-12-18T14:39:27.520 回答