如何对独立模型进行单元测试

本文关键字:单元测试 模型 独立 | 更新日期: 2023-09-27 18:32:03

我使用提到的存储库编写了以下方法在以下博客文章 (http://www.codecapers.com/post/Using-RavenDB-with-ASPNET-MVC.aspx) 中使用 RavenDB:

public User GetUserById(string id)
{
     var user = (from usr in _repository.All<User>() where usr.Id == id select usr).FirstOrDefault();
     if (user == null)
     {
          throw new NullReferenceException("No user with the id (" + id + ") could be found.");
     }
     return user;
}

您将如何使用 nunit(也许还有 moq)对此方法进行单元测试?

"用户"只是一个普通类。

如何对独立模型进行单元测试

通常,您不会直接针对存储库层编写测试。例如,假设您正在使用nHibernate或实体框架,那么针对存储库进行测试在技术上将测试该框架。

创建者或那些ORM已经做到了。

此外,与数据库通信会使测试成为集成测试而不是单元测试。

例如,您的单元测试将针对模拟存储库层的业务层。

如果你想写一个集成测试,你也可以针对业务层编写它,但不要嘲笑存储库层并让它通过。

我会执行以下操作来准备您的代码:

  1. 确保_repository是通过构造函数或属性传入的,以便可以轻松更改它进行测试。
  2. 确保将_repository变量声明为 IRepository 类型,而不是具体类型。

然后,在测试中:

  1. 创建界面的模拟并将其传递给您的_repository
  2. 重写 .All<User>() 方法以返回已知的硬编码User列表,其中包含适合测试的值。
  3. 在一个测试中断言查询现有 ID 时返回正确的值。
  4. 在单独的测试中断言,查询不存在的 ID 时会引发异常。

第一个问题是 - 在这种情况下,您正在测试什么?提供的方法实际上只有两个结果,因此您基本上是在测试user是否为空。这是增值测试吗?

至于如何,我假设_repository是通过某种机制注入的?如果是这样,那么您只需提供一个Mock<IRepository>(根据需要插入您的类型名称),并在注入_repository的位置注入它。然后,您可以设置返回值并测试您的方法是否存在异常。

mockRepository.Setup(x => x.All<User>()).Returns(new List<User> { ... });

RavenDB 是专门设计的,因此您无需模拟所有单元测试。

只需在内存中运行它,然后可以直接对它执行单元测试。有关详细信息,请参阅此博客文章。

它允许您编写如下代码:

[Fact]
public void CanQueryForDistinctItemsUsingLinq()
{
    using (var store = NewDocumentStore())
    {
        using (var s = store.OpenSession())
        {
            s.Store(new { Name = "ayende" });
            s.Store(new { Name = "ayende" });
            s.Store(new { Name = "rahien" });
            s.SaveChanges();
        }
        store.DocumentDatabase.PutIndex("test", new IndexDefinition
        {
            Map = "from doc in docs select new { doc.Name }",
            Stores = { { "Name", FieldStorage.Yes } }
        });
        using (var s = store.OpenSession())
        {
            var objects = s.Query<User>("test")
                .Customize(x => x.WaitForNonStaleResults())
                .Select(o => new {o.Name })
                .Distinct()
                .ToList();
            Assert.Equal(2, objects.Count);
            Assert.Equal("ayende", objects[0].Name);
            Assert.Equal("rahien", objects[1].Name);
        }
    }
}

这来自RavenDB单元/集成测试,所以你需要一些信息才能让它工作,但它给出了一般的想法。