如何正确地对存储库中的CRUD操作进行单元测试?

RPM*_*984 9 c# unit-testing entity-framework crud repository

意识到这可能听起来像一个广泛的问题 - 所以让我澄清一下.我有一个通过接口公开的存储库,有两个具体的实现 - 一个MockRepository和一个EntityFrameworkRepository.

现在,我对所有的测试可以对运行的单元测试项目无论是库通过弹上的线,[TestInitialize].

我的问题基本上是"我该如何编写测试".

这就是我所拥有的:

C reate

// Arrange.
var foo = new Foo { .. };

// Act
Repository.Add(foo);
UnitOfWork.Commit();

// Assert
Assert.IsTrue(foo.Id > 0);
Run Code Online (Sandbox Code Playgroud)

R etrieve

// Arrange.
var fooToGet = 1;

// Act
var foo = Repository.FindSingle(fooToGet);

// Assert
Assert.IsNotNull(foo);
Assert.AreEqual(foo.Id, fooToGet);
Run Code Online (Sandbox Code Playgroud)

ü PDATE

// Arrange.
var fooToGet = 1;
var nameToChangeFooTo = "FooBar";

// Act
var foo = Repository.FindSingle(fooToGet);
foo.Name = nameToChangeFooTo;
UnitOfWork.Commit();
var fooRetrievedAgain = Repository.FindSingle(fooToGet);

// Assert
Assert.IsNotNull(foo);
Assert.AreEqual(fooRetrievedAgain.Id, fooToGet);
Assert.AreEqual(fooRetrievedAgain.Name, nameToChangeFooTo);
Run Code Online (Sandbox Code Playgroud)

D elete

// Arrange.
var fooToGet = 1;

// Act
var foo = Repository.FindSingle(fooToGet);
Repository.Remove(foo);
UnitOfWork.Commit();
var fooRetrievedAgain = Repository.FindSingle(fooToGet);

// Assert
Assert.IsNull(fooRetrievedAgain);
Run Code Online (Sandbox Code Playgroud)

它的工作,同时为模拟和EF库,但我的主要问题是C(创建).我不确定如何测试我的存储库上的添加操作.它不觉得不对劲做IM.

它传递给EF Repository,但为了让它通过我的Mock Repository,我不得不使用反射来更新内存中的ID(讨厌).

那么 - 请您分享一些关于在存储库模式上测试CRUD操作的正确方法的建议吗?

这是一个ASP.NET MVC应用程序,.NET 4,C#,实体框架4和工作单元/存储库模式.

谢谢.

编辑

只是为了澄清一下,这些并不是我所有的单元测试.我有服务层的单元测试,以及业务规则测试.

如果我的上述存储库测试失败,后者将(并且应该)失败.这就是重点测试我的存储库的基本操作.我错了吗?

mar*_*inl 3

一种选择是使用 SqlLite 等内存数据库来测试映射、查询和存储库的行为。Ayende在这里对此进行了讨论,尽管他的示例使用了 NHibernate。

另一个选项似乎可以解决您对设置域对象 ID 的直接关注,那就是使用测试假货。RhysC在此对此进行了讨论。