【发布时间】:2017-05-24 17:01:48
【问题描述】:
我对单元测试完全陌生。我阅读了许多来自不同人的“教程”,我决定使用 msdn 解决方案。
我使用这个https://msdn.microsoft.com/en-us/library/dn314429(v=vs.113).aspx 作为我的测试,我对那里的“测试非查询场景”感兴趣。
根据这篇文章,我尝试测试我的简单 CRUD 的 Create() 操作。
这是我的代码(FinancialAssistantEntities 是我的 DbContext(EF 数据库优先)):
上下文:
public partial class FinancialAssistantEntities : DbContext
{
public FinancialAssistantEntities()
: base("name=FinancialAssistantEntities")
{
}
.
.
.
public virtual DbSet<FAWallet> FAWallet { get; set; }
}
存储库方法:(我注释掉了我的事务的 using,因为从测试方法运行它会导致错误“No connection string named 'FinancialAssistantEntities' could be found in the应用程序配置文件。”),
public async Task<bool> CreateWallet(FAWallet model)
{
using (var context = Context)
{
// transaction with IsolationLevel
//using (var tran = context.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
{
try
{
context.FAWallet.Add(model);
//context.SaveChanges();
await context.SaveChangesAsync();
//tran.Commit();
return true;
}
catch (Exception ex)
{
//tran.Rollback();
throw ex;
}
}
}
}
测试方法:
[TestMethod]
public void CreateWalletTest()
{
var wallet = new FAWallet()
{
WalletId = Guid.NewGuid(),
//WalletName = StringHelper.GenerateRandomString(12),
// admin ID
WalletUserId = "e6888245-1d9b-431c-a068-aa62932e47ec",
WalletCreateDate = DateTime.Now,
WalletEnabled = true
};
var mockSet = new Mock<DbSet<FAWallet>>();
var mockContext = new Mock<FinancialAssistantEntities>();
mockContext.Setup(x => x.FAWallet).Returns(mockSet.Object);
var walletRepository = new FAWalletRepository(mockContext.Object);
walletRepository.CreateWallet(wallet).Wait();
mockSet.Verify(x => x.Add(It.IsAny<FAWallet>()), Times.Once());
mockContext.Verify(x => x.SaveChangesAsync(), Times.Once());
}
首先,我不知道评论交易的使用是否是个好主意,虽然我对测试还不太了解。
其次,我的测试总是通过。我什至注释掉了 WalletName 属性的集合,因为该字段不可为空,所以似乎我做错了什么。
【问题讨论】:
-
您基本上是在尝试测试 EF 是否在执行其设计的任务。不要那样做。微软会在发布它以供使用之前对其进行完全测试。您可以考虑抽象存储库对上下文的依赖。
-
这个特殊的模拟框架适用于虚拟方法,这就是为什么您无法模拟代码的事务部分的原因。这是一个实现问题,可以抽象出来。测试通过,因为根据测试的设置,它将按照配置执行。
-
Nkosi:我在其他主题下阅读过与您类似的答案,但我的意思是测试我的错误,例如。在该系统自动填充其他字段之后,我有一些对象仅由用户部分填充,例如。创建日期、创建用户等。当我错过填写其中一些字段时,SaveChanges() 会给我一个错误。我不能把它放在 ModelState 验证中,因为这个数据既不是由用户填充也不是作为隐藏值传递的,它是在一般验证之后稍后填充的。当我添加新的非空字段而不填写它时,那种测试会告诉我我忘了填写它。
-
不要测试实体框架。微软已经这样做了。测试您自己的代码是否符合预期。
标签: c# entity-framework unit-testing moq