我正在尝试单元测试通过实体框架进行的存储库:
我想要发生的是测试存储库而不实际发送/连接到实际的数据库,我想这样做,而不使用任何嘲笑的框架.
目前我的测试是将数据发送到数据库,我想要发生的是测试add / remove等方法,而不会将实际数据发送到数据库,因为它仅用于测试.
这是存储库:
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); }
我想使用垫片/存根/假货来进行测试.
解决方法
实体框架存储库是您的存储库接口的具体实现.因为它是具体的,你不能抽象和测试没有数据库 – 这一具体实现的全部要写数据到数据库!
这意味着,测试EF存储库应该是旨在验证存储库写入实际数据库 – 在您调用存储库方法的测试的行为阶段,在断言阶段,您可以使用从数据库获取数据的任何其他方式(ado.net也许?)来检查存储库是否完成其工作.
另一个无关紧要的是,您可以使用存储库的另一个实现,该存储库使用内存中的数据存储,并将这些内存中的存储库注入到其他服务中,可以在不写入物理数据库的情况下测试这些服务.您甚至可以模拟一个注册到其他服务的存储库,只是为了执行一些行为测试,即测试您的服务是否正确使用您的存储库.