我应该为以下哪种方法编写单元测试?

时间:2012-12-03 16:53:34

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

我第一次看单元测试。 当我在Visual Studio 2008中时,我开始使用内置测试框架。

我按下了按钮并开始考虑填空,这一切看起来都很简单

除此之外,我可以看到两个问题。

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

的方法编写测试

我将举例说明(1)。

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

这是通过(严重简化的)代码的路径,这些代码使用了一个使用用户列表并将它们写入数据库中的Users表的方法。

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() - 只是一个for循环调用PutEntity(),它是基类的泛型方法 PutEntity() - 调用已经有单元测试的三个方法,并调用DataContext.InsertOnSubmit。

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

GetOperatorsResponse GetOperators(GetOperatorsRequest request) - 自动生成

GetOperatorsResponse GetOperatorsImplementation(GetOperatorsRequest input) - 设置DataContext

List<Operator> GetEntities() - Linq查询

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

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

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

这是接近这个的正确方法吗?

1 个答案:

答案 0 :(得分:0)

对于你应该和不应该测试的内容,没有“硬性和快速”的规则。

单元测试用于测试您的书写工作的任何实现,并使您在重新分解您没有破坏任何东西时有信心。您需要考虑您编写的测试是否会给您带来价值。

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

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

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

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