如何构建数据库调用以便于测试?

时间:2012-02-14 23:14:12

标签: unit-testing tdd

我尝过T(B)DD Kool-Aid,我坚信它的优点,特别是让我相信我的代码是正确的*

我最近一直在思考构建代码以使单元测试成为可能的最佳方法。我读过几篇不同的文章(比如this one),当然他们说远离生产数据库(我们已经在这里做了)。我觉得我对这些概念很满意,但是我在弄清楚什么是最好的代码布局时遇到了问题。目前,与数据库交互的大多数功能如下所示:

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

几乎每个查询都以同样的方式在全公司范围内编写。显然,这不适用于可测试性,因为我必须闯入函数来实际测试它。所以我在想 - 为什么不把实际的访问功能拉出来,然后我可以测试它们是否正常工作。我在想,也许我应该有一个只执行查询并返回阅读器的函数(或某种类型的表,其中包含结果)。然后,我将能够直接测试数据访问功能,这将使我能够,例如回滚事务。

是否有任何文章或问题以及用于测试此图层的“正确”方法的示例?

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

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

编辑:

为了澄清,我正在寻找如何构建我的代码进行测试,例如:我希望代码看起来像这样:

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

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

1 个答案:

答案 0 :(得分:0)

如果这是您的应用和数据库之间的边界,我会说集成测试。

应该有一个角色/接口(CustomerRepository)和一个实现(SqlCustomerRepository)。

  • 单元测试:测试应用程序的其余部分使用基于CustomerRepository接口的假/模拟。该角色从用于实现存储库的技术中抽象出应用程序
  • 集成测试:但是,您在上面发布的代码看起来像属于SqlCustomerRepository。测试它的唯一方法是调用接口方法,看看它是否适用于真正的Sql DB。这里没有嘲弄或伪造......这些测试会很慢(您可以使用类别标记它以减少运行它们)但是它们会验证SqlCustomerRepository是否满足CustomerRepository合同。