存储库模式和内存中的单元测试

Kai*_*kus 13 .net c# unit-testing repository-pattern

我已经看到了Repository Pattern的一些实现,非常简单和直观,在stackoverflow中链接形成其他答案

http://www.codeproject.com/Tips/309753/Repository-Pattern-with-Entity-Framework-4-1-and-C http://www.remondo.net/repository-pattern-example-csharp/

public interface IRepository<T>
{
    void Insert(T entity);
    void Delete(T entity);
    IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate);
    IQueryable<T> GetAll();
    T GetById(int id);
}

public class Repository<T> : IRepository<T> where T : class, IEntity
{
    protected Table<T> DataTable;

    public Repository(DataContext dataContext)
    {
        DataTable = dataContext.GetTable<T>();
    }
...
Run Code Online (Sandbox Code Playgroud)

在进行单元测试时,如何将其设置为在内存中工作?有没有办法从内存中的任何东西构建DataContext或Linq表?我的想法是创建一个集合(List,Dictionary ...)并在单元测试时将其存根.

谢谢!

编辑:我需要这样的东西:

  • 我有一本班级书
  • 我有一个班级图书馆
  • Library构造函数中,我初始化了存储库:

    var bookRepository = new Repository<Book>(dataContext)

  • 这些Library方法使用存储库,就像这样

    public Book GetByID(int bookID)
    { 
        return bookRepository.GetByID(bookID)
    }
    
    Run Code Online (Sandbox Code Playgroud)

在测试时,我想提供一个内存上下文.在生产中,我将提供真实的数据库上下文.

Mec*_*ect 19

我建议使用像MoqRhinoMocks这样的模拟库.可以在这里找到使用Moq的精彩教程.

在您决定使用哪一个之前,以下内容可能会有所帮助:

附加信息:单元测试框架的比较可以在这里找到.


根据OP的要求更新

创建内存数据库

var bookInMemoryDatabase = new List<Book>
{
    new Book() {Id = 1, Name = "Book1"},
    new Book() {Id = 2, Name = "Book2"},
    new Book() {Id = 3, Name = "Book3"}
};
Run Code Online (Sandbox Code Playgroud)

模拟你的存储库(我使用Moq作为以下示例)

var repository = new Mock<IRepository<Book>>();
Run Code Online (Sandbox Code Playgroud)

设置您的存储库

// When I call GetById method defined in my IRepository contract, the moq will try to find
// matching element in my memory database and return it.

repository.Setup(x => x.GetById(It.IsAny<int>()))
          .Returns((int i) => bookInMemoryDatabase.Single(bo => bo.Id == i));
Run Code Online (Sandbox Code Playgroud)

通过在构造函数参数中传递模拟对象来创建库对象

var library = new Library(repository.Object);
Run Code Online (Sandbox Code Playgroud)

最后一些测试:

// First scenario look up for some book that really exists 
var bookThatExists = library.GetByID(3);
Assert.IsNotNull(bookThatExists);
Assert.AreEqual(bookThatExists.Id, 3);
Assert.AreEqual(bookThatExists.Name, "Book3");

// Second scenario look for some book that does not exist 
//(I don't have any book in my memory database with Id = 5 

Assert.That(() => library.GetByID(5),
                   Throws.Exception
                         .TypeOf<InvalidOperationException>());

// Add more test case depending on your business context
.....
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢教程!但我需要测试一个使用存储库的现有类。创建一个“假”存储库并以这种方式对其进行测试只会让我测试存储库模式是否得到了很好的实现。我会尝试通过编辑来澄清我的问题 (2认同)