【问题标题】:How can I use Moq to test a method that creates a new DbContext?如何使用 Moq 测试创建新 DbContext 的方法?
【发布时间】:2020-05-04 19:19:24
【问题描述】:

我正在使用:MSTestEntity Framework 6Moq

我正在尝试使用我们预先存在的实体框架 asp.net 应用程序来学习 TDD。现在我正在使用我们的 web api,我创建了一个新的测试项目和类,我正在尝试编写一个测试,看看我是否可以至少获得一个值。所以在某些地方,我显然不得不为已经存在的代码编写测试。

这里我不知道是否/如何设置我的测试项目、类或方法(不确定哪些需要设置)以测试此方法

[HttpGet]
[ResponseType(typeof(IEnumerable<TimeZoneDTO>))]
[Route("api/timezone")]
public IHttpActionResult GetTimeZones()
{
    var _out = new IEnumerable<TimeZoneDTO>();
    using (var db = new Entities())
    {
        _out = from x in db.Timezones
               orderby x.UTCOffSet descending
               select new TimeZoneDTO() {
                   Caption = x.Name,
                   Id = x.Abbreviation
               };
    }

    return Ok(_out);
}

问题在于using (var db = new Entities()) 依赖于控制器项目的 web.config 文件中的命名数据库配置字符串。

public partial class Entities : DbContext
{
    public Entities(): base("name=Entities") {}

    ...
}

我在这里有什么选择?有没有办法让 Moq 来处理这个问题,还是我需要以某种方式更新测试项目?我不想(此时)做的是返工,这将使我不得不更改应用程序的其他核心部分。

【问题讨论】:

  • 你不能在你的单元测试项目的app.config文件中定义连接字符串吗?
  • 您的应用程序似乎缺少一点依赖注入,因此很难通过适当的单元测试来覆盖它。
  • 另外我想说你不需要将你的 _out 变量移动到外部范围。只需在您的using block ad move return 语句中使用ToList 实现查询。

标签: c# entity-framework-6 asp.net-web-api2 moq mstest


【解决方案1】:

处理此类情况的典型方法是更改​​您正在测试的类,使其注入 DbContext 本身或生成 DbContext 的工厂。这样,它不是 new自己创建 DbContext,而是依靠依赖注入配置来确定如何创建 DbContext。然后你可以mock the DbContext(使用模拟或假工厂,如果你走工厂路线)。

【讨论】:

  • 谢谢,@StriplingWarrior。这是否也意味着 DbContext 将被自动清理而不将其放置在 using 块中?
  • 如果您采用工厂方法,您仍然需要使用 using 块来处理创建的 DbContext。如果直接注入 DbContext,则需要配置依赖注入框架来处理其生命周期。通常在此模型中,生命周期应该是请求或异步范围的,因此在 Web 请求开始时会创建一个上下文,由该请求中的所有类重用,并在其结束时处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 2021-01-24
相关资源
最近更新 更多