【问题标题】:How to do unit testing for nested "using" statements in C#?如何在 C# 中对嵌套的“使用”语句进行单元测试?
【发布时间】:2018-09-25 15:57:58
【问题描述】:

我正在处理大型遗留项目。 我已经开始用 xUnit 编写单元测试。 另外,我正在使用 Moq 框架。 我在这里阅读了很多文章,但没有找到明确的答案。我坚持理解如何在测试方法中对两个 IDisposable 对象进行模拟?我想测试的方法:

public class SomeService: ISomeService
{
  ...
  public async Task<Settings> GetSettings(UserIdentity user)
    {
        SettingsDBModel dbModel;
        using (DBHelperAsync dbHelper = new DBHelperAsync(user))
        {
            using (DBHelperReaderAsync reader = await dbHelper.ExecuteReader("Stored procedure Name", new { UserID = user.UserID }))
            {
                dbModel = await reader.GetResult<SettingsDBModel>();
            }
        }
        var settings = new Settings(dbModel);
        return settings;
    }
  ...
}

我想reader.GetResult() 方法返回一些假数据。任何想法应该如何实现 DBHelperAsync 和 DBHelperReaderAsync 对象的模拟?

【问题讨论】:

  • FWIW,这里不需要额外的大括号/缩进。把它们叠起来。
  • 你需要注入DBHelperAsync
  • @juharr,实际上 OP 不应该注入 dbHelper 本身,因为该方法应该是它的所有者/处置者——而不是方法的客户端或 DI。因此,该类需要注入一个DBHelperFactory,该方法可以使用它创建自己的新DBHelperAsync 实例。然后可以模拟工厂方法以返回模拟的DBHelperAsync
  • 我第二个@GoodNightNerdPride 方法。要注入的工厂抽象将创建一次性依赖项
  • 应重构被测类以将其与DBHelperAsync 实现问题解耦。应该为运行时代码注入和配置抽象的显式依赖项。现在将允许被测类足够灵活,可以轻松地单独进行测试。

标签: c# unit-testing moq xunit


【解决方案1】:

应重构被测类以将其与DBHelperAsync 实现问题解耦。 类应该依赖于抽象而不是具体

应该为运行时代码注入和配置一个抽象的显式依赖项。现在将允许被测类足够灵活,可以轻松地单独测试。 (显式依赖原则)。

如果遗留类无法修改,则应将它们包装在可以修改的抽象中,然后注入到被测类中。

上面提供的代码需要一个IDBHelperAsyncFactory 抽象,该抽象将被注入到类中并用于创建一次性DBHelperAsync,它也应该从一次性抽象interface IDBHelperAsync : IDisposable 派生。

这将允许在测试时轻松地模拟/存根这些抽象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 2021-09-29
    相关资源
    最近更新 更多