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

uajslkp6  于 5个月前  发布在  Java
关注(0)|答案(1)|浏览(75)

我花了很多时间为下面的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;
    
    ......
}

UserVenues

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


我很期待一个解决方案。

wfveoks0

wfveoks01#

所以,如果你想测试一些JPQL查询,我认为在这里写简单的单元测试是没有帮助的,如果可能的话。你需要hibernate-core来将JPQL渲染成SQL,执行查询,Map结果等。嘲笑所有这些是不切实际的。
因此,我认为在这种情况下,与数据库的集成测试将是最合适的。您可以设置测试数据库using either 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或类似的smth应该足够了。这也只是一个例子,在真实的世界中,我强烈建议您将init sql查询提取到单独的文件等。这只是为了演示的目的。所以考虑为这个任务编写一个与spring Boot 的集成测试。
希望有帮助:)
附言:我猜UserRepository的定义有点错误-如果你想查询User实体,你应该扩展JpaRepository<User, Long>(注意第一个类型参数)。

相关问题