使用java(spring框架)和内存db测试dao类中的crud方法的正确方法是什么?

5rgfhyps  于 2021-07-15  发布在  Java
关注(0)|答案(1)|浏览(354)

我正在努力为实践写一个好的集成测试用例。到目前为止,我已经为三种方法(save、findbyid和getall方法)实现了测试用例,但是我忍不住认为这样做是错误的。
以下是我目前掌握的代码:

@ExtendWith(SpringExtension.class) 
@ContextConfiguration(classes = {DatabaseConfigs.class})
public class UserDaoImplTest {

    private DataSource dataSource;
    private Connection con;
    private UserDao userDao;

    @Autowired
    public UserDaoImplTest(@Qualifier("h2DataSource")DataSource dataSource) {
        this.dataSource = dataSource;
        userDao = new UserDaoImpl(dataSource);  
    }

    @BeforeEach
    public void setUp() throws SQLException {
            con = dataSource.getConnection();
            ScriptUtils.executeSqlScript(con, new ClassPathResource("config/schema.sql"));
            ScriptUtils.executeSqlScript(con, new ClassPathResource("config/data.sql"));  
    }
    @AfterEach
    public void tearDown() throws SQLException {
        con.close();
    }

    @Test
    @DisplayName("Test to check if the created user, using save method, is present in db.")
    public void testSave() throws SQLException {

        User user = new User("luka", "pass");
        userDao.save(user);

        String sql = "SELECT name, password from user order by id desc";
        PreparedStatement ps = con.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        boolean result = rs.next();

        assertTrue(result, "Cant retrieve inserted user");

        String name = rs.getString("name");
        String password = rs.getString("password");

        assertEquals("luka", name, "Retrieved username doesnt match.");
        assertEquals("pass", password, "Retrieved password doesnt match.");

    }
    @Test
    @DisplayName("Test to check if the getAll method is retrieving users from db.")
    public void testGetAll() {

        List<User> getAllUsers = userDao.getAll();

        assertTrue(getAllUsers.size() > 0,  "Size of retrieved users can't be 0");
    }
    @Test
    @DisplayName("Test to check if the id of a retrived user matches the id supplied.")
    public void testFindById() {
        long id = 2;
        Optional<User> userOpt = userDao.findById(id);
        assertTrue(userOpt.isPresent(), "No user retrieved");

        User user = userOpt.get();

        assertEquals(2, user.getId(), "Retrieved id of a user doesnt match the expected id.");
    }
    @Test
    public void testDelete() {      
        fail("Not yet implemented");
    }
    @Test
    public void testUpdate() {
        fail("Not yet implemented");
    }

}

例如,我想知道是否可以像这样为save方法编写一个测试:

private int getMaxId() throws SQLException  {
    String sql = "SELECT max(id) as id from user";
    PreparedStatement ps = con.prepareStatement(sql);
    ResultSet rs = ps.executeQuery();

    rs.next();
    int id = rs.getInt("id");

    ps.close();
    rs.close();

    return id;

}

@Test
@DisplayName("Test to check if the created user, using save method, is present in db.")
public void testSave() throws SQLException {

    User user = new User("luka", "pass");
    userDao.save(user);

    Optional<User> userOpt = userDao.findById(getMaxId());
    assertTrue(userOpt.isPresent,"Can't retrieve user.")

    assertTrue(result, "Cant retrieve inserted user");

    String name = rs.getString("name");
    String password = rs.getString("password");

    assertEquals("luka", name, "Retrieved username doesnt match.");
    assertEquals("pass", password, "Retrieved password doesnt match.");

}

在本例中,我使用findbyid方法测试save方法,所以我基本上是在一个测试用例中测试两个方法。这是一个好的测试方法吗,因为我认为我打破了方法隔离的规则?我想知道测试这些方法的最佳方法是什么。任何帮助是感激的,如果我的代码不好,请告诉我我做错了什么。

qvsjd97n

qvsjd97n1#

我相信你会得到一些不同的答案。但对我来说,我希望通过以下方式进行测试,确保与数据库的集成良好:
启动db(提示:docker通常会协助)
将数据库置于已知状态(加载测试数据)
调用执行某些crud操作的方法
做一些Assert
你可能听说过这样一个术语,如果你能插入/更新/删除一些数据,然后尝试用你的read方法(从crud)读回它,你就完成了一个“往返”检查。
假设一切顺利,您会得到您所期望的结果(更新的结果(用于insert/update),或者一个空集(用于delete),或者一个异常)。
如果您使用构建工具(首选gradleforme和maven,但两者都可以)来管理旋转容器的过程,这也会有所帮助。结帐https://www.testcontainers.org/ 或者https://github.com/avast/gradle-docker-compose-plugin (与gradle构建工具配合使用)

相关问题