0

我第一次看单元测试。当我在 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<Operator> GetEntities()- Linq 查询

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

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

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

这是解决这个问题的正确方法吗?

4

1 回答 1

0

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

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

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

  • 我将要编写/已经编写的代码有多大可能发生变化并需要重构?
  • 代码是主要编写自定义代码还是自动生成的 - 如果是自动生成的,那么编写测试几乎没有价值,因为您只需测试您正在使用的自动生成器就可以正常工作(并且您应该能够信任它)。

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

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

于 2012-12-03T17:11:48.273 回答