Unit testing 如何构造数据库调用以便于测试?

Unit testing 如何构造数据库调用以便于测试?,unit-testing,tdd,Unit Testing,Tdd,我已经尝过TBDD Kool Aid,我坚信它的优点,特别是它让我相信我的代码是正确的* 我最近一直在思考构建代码以使单元测试成为可能的最佳方法。我读过一些不同的文章,比如,当然他们说远离生产数据库,我们在这里已经做到了。我认为我对这些概念非常熟悉,但我在确定最佳代码布局时遇到了一些问题。目前,与数据库交互的大多数函数如下所示: Function GetSomething(ByVal someData as DataType) as ResultType Connect to datab

我已经尝过TBDD Kool Aid,我坚信它的优点,特别是它让我相信我的代码是正确的*

我最近一直在思考构建代码以使单元测试成为可能的最佳方法。我读过一些不同的文章,比如,当然他们说远离生产数据库,我们在这里已经做到了。我认为我对这些概念非常熟悉,但我在确定最佳代码布局时遇到了一些问题。目前,与数据库交互的大多数函数如下所示:

Function GetSomething(ByVal someData as DataType) as ResultType
    Connect to database
    create command/transaction
    initialise result variables
    Try
        lines and lines of SQL
        add parameters
        perform query
        While reader.read()
           read data into result variables
        End While
    Catch ex as DB2Exception 'Since we use db2, of course
        Do stuff
    Finally
        Clean up database variables
    End Try
    return results
End Function
Property Testing as Boolean
Public Sub SomeInsertOrUpdateStatement(ByVal param as DataType)
    OpenConnection()
    Try
        If Testing Then
            ' Do one thing
        Else
            ' Do another thing
        End If
     Finally
        CloseConnection()
     End Try
End Sub
在整个公司范围内,几乎每个查询都是以相同的方式编写的。显然,这不利于可测试性,因为我必须深入到函数中来实际测试它。所以我在想——为什么不把实际的访问函数拉出来,然后我就可以测试它们是否正常工作了。我在想,也许我应该有一个函数,它只执行查询并返回读取器或某种类型的表,其中包含结果。然后我就可以直接测试数据访问功能,这将使我能够,比如说回滚事务

有没有关于测试该层的正确方法的文章或问题

我们在这里使用VB和C,但我认为这个概念与语言无关,阅读更常见的编程语言也没有问题

*至少和我的测试一样正确

编辑: 为了澄清这一点,我正在寻找如何构造用于测试的代码,例如,我不想要这样的代码:

Function GetSomething(ByVal someData as DataType) as ResultType
    Connect to database
    create command/transaction
    initialise result variables
    Try
        lines and lines of SQL
        add parameters
        perform query
        While reader.read()
           read data into result variables
        End While
    Catch ex as DB2Exception 'Since we use db2, of course
        Do stuff
    Finally
        Clean up database variables
    End Try
    return results
End Function
Property Testing as Boolean
Public Sub SomeInsertOrUpdateStatement(ByVal param as DataType)
    OpenConnection()
    Try
        If Testing Then
            ' Do one thing
        Else
            ' Do another thing
        End If
     Finally
        CloseConnection()
     End Try
End Sub

但我不完全确定最好的代码应该是什么样子。

如果这是应用程序和数据库之间的界限,我会说集成测试

应该有一个角色/接口CustomerRepository和一个实现SQLCustomerRepository

单元测试:要测试应用程序的其余部分,请使用基于CustomerRepository界面的假/模拟。角色从用于实现存储库的技术中提取应用程序 集成测试:但是,您上面发布的代码看起来属于SqlCustomerRepository。测试它的唯一方法是调用接口方法,看看它是否能与真正的Sql DB一起工作。这里没有嘲弄或伪装。。。这些测试会很慢—您可以用一个类别标记它以减少运行它们的频率,但它们会验证SqlCustomerRepository是否满足CustomerRepository约定。
我想我的问题还不够清楚,这就是我在回家前发布的内容我对测试的时间/地点/原因/方式相当满意,它构建了我的DB调用代码,用于测试,这是我正在努力解决的问题。我更新了我的问题,希望能更清楚一点。@WayneWerner-我的答案是,由于您正在编写的类看起来像是负责从数据库中获取内容的类,您应该编写集成测试-您的代码不需要更改。您只需要使用参考数据库运行一些测试。您肯定不希望在代码中测试某种标志。此外,该层不能模拟DB层,因为这样就没有什么可测试的了。您应该明确避免将生产代码与这些测试布尔值混为一谈。您应该能够在不引用任何测试用例的情况下发布生产代码。您的测试用例应该包含在引用生产代码的单独项目中。