Spock 在 Groovy 中测试结果集

Spock testing a ResultSet in Groovy

这是我目前的情况:

def "If there are results then return true otherwise return false"() {
    given:
    ResultSet resultSet = Mock()

    expect:
    resultSet.next()
}

我正在尝试测试 class CheckActuateProjectSetServiceImpl 中的布尔方法 checkIfRowExists(int id, int foreignKey)。如果行存在,则 returns 为真,否则为假。

我该如何解决这个问题?

public boolean checkIfRowExists(int id, int foreignKey){
    Resultset resultSet = checkIfRowExistsResultSet(id, foreignKey)

    return false;
}

上述方法目前还没有正确的实现,因为我试图在实现解决方案之前先编写测试。

谢谢

如果我在你那里,我会执行接下来的 TDD 步骤。

  1. 从仅针对一个测试用例的测试开始:

    def "If there not are results then return false"() {
        given:
        def service = new CheckActuateProjectSetServiceImpl()
    
        expect:
        !service.checkIfRowExists(1, 2)
    }
    
  2. 实现方法满足测试:

    boolean checkIfRowExists(int id, int foreignKey) {
        return false;
    }
    
  3. 当有一些结果时为案例添加新测试:

    def "If there are results then return true"() {
        given:
        def service = new CheckActuateProjectSetServiceImpl()
    
        expect:
        service.checkIfRowExists(1, 2)
    }
    
  4. 现在我们被迫实施我们的方法。该方法将执行数据库查询并检查实际结果集是否为空。因为数据库查询超出了单元测试范围,所以我们将其提取到一个单独的方法中,稍后将在测试中覆盖它:

    boolean checkIfRowExists(int id, int foreignKey) throws SQLException {
        ResultSet resultSet = getResultSet(id, foreignKey);
        return resultSet.next();
    }
    
    ResultSet getResultSet(int id, int foreignKey) {
        return null; // TODO should be implemented
    }
    
  5. 现在我们的测试失败了 NullPointerException 因为 getResultSet() returns null。让 return 一个模拟的 ResultSet returns truenext() 调用:

    def "If there are results then return true"() {
        given:
        ResultSet mockedResultSet = Mock(ResultSet)
        mockedResultSet.next() >> true
    
        def service = new CheckActuateProjectSetServiceImpl() {
            @Override
            def ResultSet getResultSet(int id, int foreignKey) {
                return mockedResultSet;
            }
        }
    
        expect:
        service.checkIfRowExists(1, 2)
    }
    

    测试现在是绿色的。

  6. 第一个测试也将被修复,模拟到 return false on next() call:

    def "If there not are results then return false"() {
        given:
        ResultSet mockedResultSet = Mock(ResultSet)
        mockedResultSet.next() >> false
    
        def service = new CheckActuateProjectSetServiceImpl() {
            @Override
            def ResultSet getResultSet(int id, int foreignKey) {
                return mockedResultSet;
            }
        }
    
        expect:
        !service.checkIfRowExists(1, 2)
    }
    

希望对您有所帮助。这些步骤只是以 TDD 风格前进的方向。当然,您的现实是不同的,可能需要比我上面建议的更具体的东西。