C# EF Moq单元测试,不确定验证
我对单元测试完全陌生。我从不同的人那里读了很多“教程”,我决定使用msdn解决方案 我将此用作测试,我对“测试非查询场景”感兴趣 根据本文,我尝试测试我的简单CRUD的Create()操作 这是我的代码(FinancialAsistanties是我的DbContext(EF数据库优先)): 上下文:C# EF Moq单元测试,不确定验证,c#,entity-framework,unit-testing,moq,C#,Entity Framework,Unit Testing,Moq,我对单元测试完全陌生。我从不同的人那里读了很多“教程”,我决定使用msdn解决方案 我将此用作测试,我对“测试非查询场景”感兴趣 根据本文,我尝试测试我的简单CRUD的Create()操作 这是我的代码(FinancialAsistanties是我的DbContext(EF数据库优先)): 上下文: public partial class FinancialAssistantEntities : DbContext { public FinancialAssistantEntities
public partial class FinancialAssistantEntities : DbContext
{
public FinancialAssistantEntities()
: base("name=FinancialAssistantEntities")
{
}
.
.
.
public virtual DbSet<FAWallet> FAWallet { get; set; }
}
[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());
}
public部分类金融系统:DbContext
{
公共财政系统()
:base(“名称=金融系统”)
{
}
.
.
.
公共虚拟数据库集{get;set;}
}
存储库方法:(我用注释掉了我事务的,因为从测试方法运行它会导致错误“在应用程序配置文件中找不到名为'FinancialAsistanteties'的连接字符串”。)
公共异步任务CreateWallet(FAWallet模型)
{
使用(var context=context)
{
//具有IsolationLevel的事务
//使用(var-tran=context.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
{
尝试
{
context.FAWallet.Add(model);
//SaveChanges();
wait context.saveChangesSync();
//trans.Commit();
返回true;
}
捕获(例外情况除外)
{
//事务回滚();
掷骰子;
}
}
}
}
测试方法:
public partial class FinancialAssistantEntities : DbContext
{
public FinancialAssistantEntities()
: base("name=FinancialAssistantEntities")
{
}
.
.
.
public virtual DbSet<FAWallet> FAWallet { get; set; }
}
[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());
}
[TestMethod]
公共无效CreateWalletTest()
{
var wallet=新的FAWallet()
{
WalletId=Guid.NewGuid(),
//WalletName=StringHelper.GeneratorDomainString(12),
//管理员ID
WalletUserId=“e6888245-1d9b-431c-a068-aa62932e47ec”,
WalletCreateDate=日期时间。现在,
WalletEnabled=真
};
var mockSet=new Mock();
var mockContext=new Mock();
mockContext.Setup(x=>x.FAWallet).Returns(mockSet.Object);
var walletRepository=新的FAWalletRepository(mockContext.Object);
walletRepository.CreateWallet(wallet.Wait();
验证(x=>x.Add(It.IsAny()),Times.Once());
验证(x=>x.saveChangesSync(),Times.Once());
}
首先,我不知道使用out注释事务是否是个好主意,尽管我对测试知之甚少
第二,我的考试总是通过。我甚至注释掉了WalletName属性的集合,因为该字段不能为空,所以似乎我做错了什么。前言
在我们开始检查您的问题之前,让我明确一点,主要问题不是单元测试。取而代之的,是关于和一些分析
问题空间分析
让我们看看你在评论中写了什么:
我在其他帖子中也读过类似的答案,但我的意思是
例如,测试我的错误。我有一些由用户填充的对象
只有部分,在系统自动填充其他字段之后,
例如创建日期、创建用户等,当我错过填写一些
这些字段,SaveChanges()
将向我抛出一个错误
您从错误的角度处理此任务
我为什么这么说?因为:
- 您将代码与EF紧密耦合,并带有不必要的依赖项
- 这使得测试业务逻辑变得既困难又缓慢
- 业务逻辑是代码中最重要和最有价值的部分之一,在理想的情况下,您最终会得到报酬
结局好,一切都好
当然,这一切都是有代价的。也就是说,当你把某些东西从系统中分离出来的时候,你可能会引入另一个间接层。这就是您现在需要将“域模型”映射到EF持久性模型,反之亦然。您基本上是在尝试测试EF是否正在执行其设计目的。不要那样做。微软会在发布使用之前对其进行全面测试。您可以考虑抽象化对上下文的依赖性。这个特定的模拟框架使用虚拟方法工作,这就是为什么您无法模拟代码的事务部分。这