我目前正在尝试对通过Entity Framework制作的存储库进行单元测试:
我想要发生的是在没有实际发送/连接到实际数据库的情况下测试存储库,我希望不使用任何模拟框架。
目前我的测试是将数据发送到数据库,我想要发生的是测试添加/删除等方法而不将实际数据发送到数据库,因为它仅用于测试。
这是存储库:
namespace AbstractFactory.Repository
{
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
/// <summary>
/// This class serves as the structure of the Author repository using a database
/// </summary>
public class DbAuthorRepository : IRepository<AuthorEntity>
{
private AbstractFactoryPatternEntities context;
public DbAuthorRepository(AbstractFactoryPatternEntities context)
{
this.context = context;
}
/// <summary>
/// Adds the specified author.
/// </summary>
/// <param name="author">The author.</param>
public void Add(AuthorEntity author)
{
context.AuthorEntities.Add(author);
}
/// <summary>
/// Removes the specified author.
/// </summary>
/// <param name="author">The author.</param>
public void Remove(AuthorEntity author)
{
this.context.AuthorEntities.Remove(author);
}
/// <summary>
/// Saves this instance.
/// </summary>
public void Save()
{
this.context.SaveChanges();
}
/// <summary>
/// Gets all.
/// </summary>
/// <returns>returns a list of all the authors</returns>
public IEnumerable<AuthorEntity> GetAll()
{
List<AuthorEntity> result = this.context.AuthorEntities.Include(a => a.Books).ToList();
return result;
}
/// <summary>
/// Gets the author by id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns>returns an entity</returns>
public AuthorEntity GetById(int id)
{
AuthorEntity result = this.context.AuthorEntities.Single(a => a.AuthorId == id);
return result;
}
}
}
以下是单元测试的当前代码:
[TestMethod]
public void Add_MethodIsCalled_EntityCountIsIncrementedByOne()
{
using (ShimsContext.Create())
{
ShimAbstractFactoryPatternEntities context = new ShimAbstractFactoryPatternEntities(new AbstractFactoryPatternEntities());
DbAuthorRepository repository = new DbAuthorRepository(context);
repository.Add(new AuthorEntity { FirstName = "Test", LastName = "testing=" });
var actual = repository.GetAll().Count();
repository.Save();
var expected = repository.GetAll().Count();
Assert.AreNotEqual(actual, expected);
}
//AbstractFactoryPatternEntities context = new AbstractFactoryPatternEntities();
//DbAuthorRepository repository = new DbAuthorRepository(context);
//var actual = repository.GetAll().Count();
//repository.Add(new AuthorEntity { FirstName = "Testing", LastName = "MyTest" });
//repository.Save();
//var expected = repository.GetAll().Count();
//Assert.AreNotEqual(actual, expected);
}
[TestMethod]
public void Remove_MethodIsCalled_EntityCountRemainsTheSame()
{
AbstractFactoryPatternEntities context = new AbstractFactoryPatternEntities();
DbAuthorRepository repository = new DbAuthorRepository(context);
AuthorEntity newAuthor = new AuthorEntity { FirstName = "Testing", LastName = "MyTest" };
repository.Add(newAuthor);
repository.Save();
var actual = repository.GetAll().Count();
Console.WriteLine(actual);
repository.Remove(newAuthor);
var expected = repository.GetAll().Count();
Console.WriteLine(expected);
Assert.AreEqual(actual, expected);
}
[TestMethod]
public void Get_MethodIsCalled_CorrectAuthorIsRetrieved()
{
AbstractFactoryPatternEntities context = new AbstractFactoryPatternEntities();
DbAuthorRepository repository = new DbAuthorRepository(context);
int target = 4;
AuthorEntity author = repository.GetById(target);
Assert.AreEqual(target, author.AuthorId);
}
我想使用shims / stub / fakes来进行测试。
答案 0 :(得分:17)
实体框架存储库是存储库接口的具体实现。因为它是具体的,你不能抽象它并在没有数据库的情况下进行测试 - 这个具体实现的重点是将数据写入数据库!
这意味着测试EF存储库的目的应该是验证存储库是否写入实际数据库 - 在测试的行为阶段调用存储库方法,在断言阶段,您可以使用任何其他方式从数据库获取数据( ado.net或许?)检查存储库是否能完成它的工作。
另一个不相关的事情是,您可以使用存储库的另一个实现,该存储库使用内存数据存储并将这样的内存存储库注入其他服务,允许您在不写入物理数据库的情况下测试这些服务。您甚至可以模拟注入其他服务的存储库,只是为了执行一些行为测试,即测试您的服务是否正确使用您的存储库。
答案 1 :(得分:6)
您可以使用内存数据库替换数据库连接,例如Effort。然后,您可以测试您的存储库逻辑。更多细节可以找到here