如何以标准方式编写 JPQL 连接查询的测试用例?

问题描述 投票:0回答:1

我花了很多时间来识别以下 JPQL 连接查询的单元测试用例。以下是我的实施细节。我找不到为存储库层编写测试用例的正确方法。

存储库类

@Repository
public interface UserRepository extends JPARepository<User, Integer> {

    @Query("select u from User u join fetch u.venues uv where u.eventId = :eventId")
    User findUserByEventId(String eventId);
......
}

用户类别

public class User{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int userId;
    
    private String firstName;
    
    private String lastName;
    
    @OneToMany(targetEntity = UserVenues.class, mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<UserVenues> venues;
    
    private String eventId;
    
    ......
}

用户场地

public class UserVenues{
    @Id
    private int id;
    
    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "user_Id",  referencedColumnName = "id")
    private User user;
    ......  
}   

我热切期待解决方案。

java spring-boot junit5 data-jpa-test
1个回答
0
投票

因此,如果您想测试一些 JPQL 查询,我认为在这里编写简单的单元测试可能没有帮助。您将需要

hibernate-core
将 JPQL 渲染为 SQL、执行查询、映射结果等。模拟所有这些都是不切实际的。

所以我认为在这种情况下,与数据库进行集成测试是最合适的。您可以使用 H2 设置测试数据库 ,也可以使用 testcontainers。由于您使用的是 JPQL,因此这两种方法应该都能很好地工作,尽管我仍然建议使用 testcontainers 以避免在 H2 道路上遇到不同的兼容性问题。

因此,设置测试容器后,您可以执行以下操作:

@SpringBootTest
public class MyIntegrationTest {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DataSource dataSource;

    @BeforeEach
    void setUp() throws SQLException {
        ScriptUtils.executeSqlScript(
          dataSource.getConnection(),
          new ByteArrayResource("""
            DELETE FROM user_venues;
            DELETE FROM users;
            
            INSERT INTO users(first_name, last_name. event_id) VALUES('bob', 'wasowski', '123');
            INSERT INTO user_venues(id, user_id) VALUES(1, (SELECT id FROM users WHERE event_id = '123' LIMIT 1));
            """.getBytes())
        );
    }

    @Test
    void testJoinQuery() {
        User something = userRepository.findUserByEventId("something");

        Assertions.assertThat(something).extracting(User::getFirstName).isEqualTo("Bob");
        Assertions.assertThat(something).extracting(it -> it.getVenues().size()).isEqualTo(2);
    }
}

严格来说,

@SpringBootTest
并不是那么必要,如果您只想测试存储库层,
@DataJpaTest
或类似的东西就足够了。 这又只是一个示例,在现实世界中,我强烈建议您将 init sql 查询提取到单独的文件等中。这仅供您用于演示目的。因此考虑使用 Spring Boot 来为此任务编写一个集成测试。

希望有帮助:)

P.S:我想定义

UserRepository
有点错误 - 如果你想查询
JpaRepository<User, Long>
实体,你应该扩展
User
(注意第一个类型参数)。

© www.soinside.com 2019 - 2024. All rights reserved.