我想弄明白单元测试中的嘲弄,并将单元测试过程集成到我的项目中。所以我一直在通过几个教程,并重构我的代码来支持嘲笑,无论如何,我无法通过测试,因为我试图测试的数据库方法是使用事务,但创建事务时,我得到获取过去的实体框架BeginTransaction
底层提供程序在打开时失败。
没有交易一切正常。
我目前拥有的代码是:被测
[TestMethod]
public void Test1()
{
var mockSet = GetDbMock();
var mockContext = new Mock<DataContext>();
mockContext.Setup(m => m.Repository).Returns(mockSet.Object);
var service = new MyService(mockContext.Object);
service.SaveRepository(GetRepositoryData().First());
mockSet.Verify(m => m.Remove(It.IsAny<Repository>()), Times.Once());
mockSet.Verify(m => m.Add(It.IsAny<Repository>()), Times.Once());
mockContext.Verify(m => m.SaveChanges(), Times.Once());
}
// gets the DbSet mock with one existing item
private Mock<DbSet<Repository>> GetDbMock()
{
var data = GetRepositoryData();
var mockSet = new Mock<DbSet<Repository>>();
mockSet.As<IQueryable<Repository>>().Setup(m => m.Provider).Returns(data.Provider);
// skipped for brevity
return mockSet;
}
代码:
private readonly DataContext _context;
public MyService(DataContext ctx)
{
_context = ctx;
}
public void SaveRepositories(Repository repo)
{
using (_context)
{
// Here the transaction creation fails
using (var transaction = _context.Database.BeginTransaction())
{
DeleteExistingEntries(repo.Id);
AddRepositories(repo);
_context.SaveChanges();
transaction.Commit();
}
}
}
我试图嘲弄交易部分,以及:
var mockTransaction = new Mock<DbContextTransaction>();
mockContext.Setup(x => x.Database.BeginTransaction()).Returns(mockTransaction.Object);
但这不起作用,失败:
无效设置在非虚拟(在VB重写)成员:CONN => conn.Database.BeginTransaction()
任何想法如何解决此问题?
这种设计模式很有意义,我会努力去理解它。尽管我仍然无法实现它,因为我不能嘲笑'DbContextTransaction',因为它只有内部构造函数,这似乎是'Moq'的一个问题。无论如何,它认为测试执行并不依赖于它的工作,如果我不经过调试就运行测试,它们会通过,除非我明确检查是否有任何异常被抛出。这很好。感谢洞察力,除非有更好的发现,否则我会接受。 (y) –
你可以在那里得到同样的技巧 - 创建一个由'DbContextTransactionAdapter'实现的'IDbContextTransaction'接口,它包装一个实际的'DbContextTransaction' - 并且在你的测试中模拟'IDbContextTransaction'。这有点麻烦,但这个技巧通常会使使用库代码的代码更容易测试,并且与库更紧密地耦合。 –
最近有一件事让我惊讶,当我做了Mock.Of是模拟的数据库属性创建一个具体的数据库对象使用app.config中的连接信息。因此,任何Database.ExecuteSql都可能会针对该数据库运行。还从BeginTransaction返回了具体的事务。这是怎么回事,一个模拟回报真实的东西? –