4

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

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)对这种方法进行单元测试?

“用户”只是一个普通的类。

4

4 回答 4

2

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

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

与数据库交谈也会使您的测试成为集成测试而不是单元测试。

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

如果您想编写集成测试,您也可以针对业务层编写它,但不要模拟存储库层并让它通过。

于 2012-04-24T14:49:49.567 回答
1

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

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

然后,在您的测试中:

  1. 创建一个模拟界面并将其传递给您的_repository.
  2. 覆盖该.All<User>()方法以返回一个已知的硬编码列表,User其中包含适合您的测试的值。
  3. 在一项测试中断言当您查询现有 ID 时返回正确的值。
  4. 在单独的测试中断言当您查询不存在的 ID 时会引发异常。
于 2012-04-24T14:52:19.757 回答
0

第一个问题是——在这种情况下你要测试什么?提供的方法实际上只有两个结果,所以你基本上是在测试是否user为空。那是增值测试吗?

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

mockRepository.Setup(x => x.All<User>()).Returns(new List<User> { ... });
于 2012-04-24T14:53:03.703 回答
0

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单元/集成测试,因此您需要一些基础设施才能使其正常工作,但它提供了总体思路。

于 2012-04-24T20:07:48.440 回答