1

以下是我的方法

User UpdateUser(User user)
{
}

每当要测试此方法时,我都会进行如下测试。

我几乎写了 20 到 30 个测试用例。

在那,我使用了以下方法。

对于每个测试用例,我创建了 User 对象并提供了必要的输入并提供了错误的输入以进行检查,最后我将删除在 DB 中更新的用户详细信息。

例如

[TestMethod]
void test1()
{
    try
    {
        // Here will call updateUser and do necessarry check
    }
    finally
    {
        // here I'll delete user details from DB
    }
}

[TestMethod]
void test2()
{
    try
    {
        // Here will call updateUser and do necessarry check
    }
    finally
    {
        // here I'll delete user details from DB
    }
}

那是正确的单元测试方式吗?

因为,如果我使用 TestInitialize,每个测试用例也会调用它。

我是以正确的方式做事还是有其他方法?

4

3 回答 3

4

不,这不是正确的方法,因为这不再是单元测试,而是集成测试。单元测试不应该触及数据库。而是使用模拟和存根来模仿行为。

如果您的问题是关于集成测试的,那么它有点基于意见。这取决于您的需求和偏好,只要它能满足您的需求。我已经看到了多种方法来处理这种情况。最重要的是要保持一致。一旦你选择了一种方法,就一直坚持到项目完成,这样你就不会混合多种编程风格。

于 2013-10-23T11:07:51.960 回答
1

你可以使用一个TransactionScope

[TestMethod]
void test1()
{
  using (var scope = new TransactionScope(TransactionScopeOption.Required))
  {
    // Here will call updateUser and do necessarry check

    //just never call scope.Complete() and alle your db changes will be rolled back
  }
}

测试完成后(即使它因异常而失败),对数据库的更改将回滚,您不需要自己进行清理
就效率而言,我不确定这是一个好的方法,但它肯定更容易: )

于 2013-10-23T11:11:37.120 回答
0

如果您可以将方法更改为无效,则该方法将更容易测试,对我来说它也更有意义。现在你的方法做了两件事(1)更新用户和(2)返回用户。测试做一件事的方法总是更容易。

您不应该在单元测试中使用数据库 - 模拟它。可以这样想;您应该能够在没有互联网连接的情况下运行测试等等。如果代码在没有外部系统可访问的情况下在上下文中编译,您的单元测试应该能够在相同的上下文中执行。

如果您无法控制 UpdateUser 类,则不应对其进行单元测试。如果您的代码依赖于它,您需要模拟 UpdateUser 以便您可以测试您的类。

于 2013-10-23T12:01:44.250 回答