【问题标题】:Which of the following methods should I write unit tests for?我应该为以下哪种方法编写单元测试?
【发布时间】:2012-12-04 01:11:48
【问题描述】:

我是第一次看单元测试。 当我在 Visual Studio 2008 中时,我从构建测试框架开始。

我已经按下按钮并开始查看填空,这一切似乎相当简单。

除了,我可以看到两个问题。

1) 很多空白单元测试似乎是多余的,是否有经验法则可以选择 为哪些方法编写单元测试。 2)是否有为读取/写入数据库的方法编写测试的最佳实践(本例中为 SQL Server)

我将举例说明 (1)。

我正在为 WCF Web 服务编写单元测试。我们首先使用 wscf.blue 来编写我们的 Web 服务 WSDL/XSD。

这是使用用户列表并将其写入数据库中的用户表的方法的(高度简化的)代码的路径。

Entry Point
   |
   |
   V
void PutOperators(PutOperatorsRequest request) (This method is auto generated code)
   |
   |
   V
void PutOperatorsImplementation(PutOperatorsRequest input) (Creates a data context and a transaction, top level exception handling)
   |
   |
   V
void PutEntities<T>(IEnumerable<T> input) (Generic method for putting a set of entities into the database, just a for loop, T is Operator in this case)
   |
   |
   V
U PutEntity<T, U>(T entity) (Generic Method for converting the input to what the database expects and adding it to the DataContext ready for submission, T is Operator, U is the data layer entity, called User)
   |
   |
   V
(This method calls 3 methods, first 2 of which are methods belonging to "entity" passed into this method, the 3rd is an abstract method that, when overridden,  knows how to consume a BL entity and flatten it to a database row)
void EnsureIDPresent() (Ensures that incoming entity has a unique ID, or creates one)
void ValidateForInsert(AllOperators) (Does this ID already exists, etc)
User ToDataEntity(Operator entity) (simple field mapping excersice, User.Name = Operator.Name, etc)

所以,据我所知,我有 3 种方法可以做一些明显可测试的事情:

EnsureIDPresent() - 此方法以易于测试的方式接受和输入并修改它 ValidateForInsert() - 此方法接受输入并在不满足条件时抛出异常 ToDataEntity() - 此方法接受输入,创建数据行实体并填充值。应该很容易测试。

还有:

PutOperatorsImplementation() - 在这里调用 DataContext.SubmitChanges() 和 TransactionScope.Complete()。我应该编写测试来测试写入数据库的内容吗?然后什么?删除他们的记录?不知道在这里做什么。

我想我应该删除以下测试:

PutOperators() - 自动生成的代码,一行,调用 PutOperatorsImplementation() PutEntities()- 只是一个调用 PutEntity() 的 for 循环,它是基类上的通用方法 PutEntity() - 调用三个已经有单元测试的方法和调用 DataContext.InsertOnSubmit。

我也有类似的获取数据的途径:

GetOperatorsResponse GetOperators(GetOperatorsRequest request) - 自动生成

GetOperatorsResponse GetOperatorsImplementation(GetOperatorsRequest input) - 设置数据上下文

List&lt;Operator&gt; GetEntities() - Linq 查询

Operator ToOperator(User) - 将一个数据实体展平为等效的 BL 实体。

我想我应该只是测试ToOperator()GetEntities()

我应该只拥有一个包含已知良好测试数据的专用测试数据库吗?

这是处理这个问题的正确方法吗?

【问题讨论】:

    标签: c# unit-testing visual-studio-2008


    【解决方案1】:

    对于应该和不应该测试什么没有“硬性规定”。

    单元测试可以测试您编写的任何实现,并让您在重构时确信您没有破坏任何东西。您需要考虑您编写的测试是否会给您带来价值。

    在决定要覆盖哪些代码时需要考虑的主要事项是

    • 我将要编写/已经编写的代码的可能性有多大 改变并需要重构?
    • 代码是主要编写自定义代码还是自动生成 - 如果 自动生成然后编写测试没有什么价值,因为你 只需测试您正在使用的自动生成器就可以了 正确(并且您应该能够信任它)。

    您不应使用数据库或任何可以在测试环境之外更改的东西来测试数据访问代码。相反,请考虑编写“Mocks”来模拟来自数据层的响应以进行测试。这将确保您的测试是一致的。考虑查看一些模拟框架,例如 Rhino Mocks 或 MOQ。

    永远记住,你写测试是有原因的,而不是为了写测试。如果您不会从您编写的测试中获得任何价值(例如,如果您的代码库不会改变),那么就不要编写它们。

    【讨论】:

    • 好的,有道理,谢谢。我已经开始阅读 Rhino 手册,我想我看到了我们如何做事的一个直接问题。我们有很多对静态属性的调用,该属性查找当前范围内的 DataContext。我猜这种模拟方法只有在您传递信息存储库时才有效?我们只是将它们从以太中提取出来......
    • 如果您也从物理传感器或硬件读取数据,Mocks 也会很有用,这样您就不必在单元测试期间确保硬件处于特定状态。
    • 听起来对手持设备测试很有用,我们使用 GPS、GPRS 等
    • 有人知道使用 Rhino 模拟 DataContext 的指南吗?
    猜你喜欢
    • 2014-10-01
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    相关资源
    最近更新 更多