如何对IRepository进行单元测试?

时间:2012-04-24 14:42:42

标签: c# unit-testing nunit repository ravendb

我使用提到的Repository编写了以下方法 在使用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)对此方法进行单元测试?

“user”只是一个普通的类。

4 个答案:

答案 0 :(得分:2)

通常,您不会直接针对存储库层编写测试。 比如说你正在使用nHibernate或Entity Framework,而不是对存储库的测试在技术上会测试该框架。

创作者或那些ORM已经完成了。

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

您的单元测试将针对模拟存储库层的业务层进行测试。

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

答案 1 :(得分:1)

我会做以下准备你的代码:

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

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

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

只需在内存中运行它,然后您就可以直接对它执行单元测试。有关详细信息,请参阅this blog post

它允许你编写这样的代码:

[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 unit/integration tests,所以你需要一些基础设施才能让它工作,但它提供了一般的想法。