【问题标题】:Rhino mocks for accessing database用于访问数据库的 Rhino 模拟
【发布时间】:2013-04-09 21:16:10
【问题描述】:

如果以前有人问过这个问题,请原谅。 我正处于搜索示例返回太多结果让我感到困惑的阶段。

我是 Rhino 模拟的新手,我知道有很多示例,但界面 - 虚拟推荐让我感到困惑。

如果我的课程运行良好(但我必须对每一行代码进行单元测试),我是否必须调整我的代码以满足单元测试的要求?还是应该反过来?

说到重点,我有以下课程,我想模拟一下。

public class DatabaseOperation
{
    public IList<T> GetRecords<T>(string connectionString, string storedProcedureName)
    {
        using (var connection = new SqlConnection(connectionString))
        {
            connection.Open();
            using (var command = connection.CreateCommand())
            {
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = storedProcedureName;
                var reader = command.ExecuteReader();
                var fillSelection = new FillSelection<T>();
                return fillSelection.GetSelection(reader);
            }
        }
    }
}

我该怎么做?

【问题讨论】:

  • 你必须在停止单元测试的地方画一条线。就我个人而言,我倾向于将上述标准样板代码视为不需要测试。如果您必须“测试”它,您需要模拟 SQLConnection 并将其注入到此代码中,这样您就可以测试您的代码如何与之交互。但我认为这将是浪费时间。更重要的问题是你怎么知道 SP 做了它应该做的事情。
  • 问题是代码是用代码质量控制来监控的,对于非技术用户来说,这个工具的结果是唯一的参考。如果我不对所有代码进行单元测试,那么质量指示器将为红色。所以我必须测试它。 (这是与数据库交互的许多其他代码的一部分,所以我希望有一个解决方案,并尝试找出其余的。
  • 然后以某种方式将 SqlConnection 的 Mock 注入代码中。您将不得不屈服于代码以使其可测试 - 这是没有意义的。但是,如果您无法向您的“客户”解释这一点,那么您别无选择。如果我没记错的话,SqlConnection 上有一个 IDbConnection 接口,这可能是 Mock 的基础。
  • 您应该修改您的指标以将这种情况考虑在内,至少就代码覆盖率而言。这比对 .NET 框架进行单元测试要好。

标签: c# unit-testing nunit rhino-mocks


【解决方案1】:

如果你想测试方法本身,你应该在其中添加一个依赖。这意味着使用 IDbConnection 代替 SqlConnection 并将其用作参数而不是连接字符串。 然后你可以模拟输入参数和测试方法的行为。例如,如果 IDbConnction.Open 方法被调用,或者所有方法都以正确的顺序调用。

您的方法应具有以下签名:

public IList<T> GetRecords<T>(IDbConnection connection, string storedProcedureName)

在您的测试中,您可以使用以下语句:

IDbConnection connectionMock = MockRepository.GenerateMock<IDateTimeProvider>(IDbConnection);

// initialize mock object and your class here

yourClassInstance.GetRecords(connectionMock, yourProcedureName);

dateTimeProviderMock.AssertWasCalled(connection => connection.Open());

【讨论】:

    【解决方案2】:

    总有某些部分不能用 rhino 之类的框架进行真正的单元测试,你可以用 TypeMock Isolator 之类的框架对其进行测试,但这不是免费的。

    如果您愿意,您可以测试此代码,但这将是一个集成测试,而不是一个单一的测试,这意味着您需要一个包含假数据的真实数据库才能通过此测试。这将为您提供 100% 的代码覆盖率,但您必须注意,它不仅可能被这部分代码破坏,而且还存在与集成相关的问题。

    我有几个软件项目同时具有单一和集成自动测试,并且我在运行所有这些项目时都取得了巨大的成功。

    【讨论】:

    • 只是为了补充这篇文章,你应该看看 SpecFlow,你可以编写应该​​进行集成测试的用户验收测试。
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    相关资源
    最近更新 更多