我使用提到的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”只是一个普通的类。
答案 0 :(得分:2)
通常,您不会直接针对存储库层编写测试。 比如说你正在使用nHibernate或Entity Framework,而不是对存储库的测试在技术上会测试该框架。
创作者或那些ORM已经完成了。
与数据库通信也会使您的测试成为集成测试,而不是单元测试。
您的单元测试将针对模拟存储库层的业务层进行测试。
如果您想编写集成测试,您还要针对业务层编写,但不要模拟存储库层并让它通过。
答案 1 :(得分:1)
我会做以下准备你的代码:
_repository
,以便可以轻松更改它以进行测试。_repository
变量声明为IRepository
类型,而不是具体类型。然后,在你的测试中:
_repository
。.All<User>()
方法,返回已知的,经过硬编码的User
列表,其中包含适合您测试的值。答案 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,所以你需要一些基础设施才能让它工作,但它提供了一般的想法。