当使用带有接口的存储库模式时,我如何使用实体框架和Moq进行单元测试



我是测试新手,工作中的任务是在MVC EF核心存储库上为我使用MSTest编写的一些代码设置一些简单的CRUD测试。

get方法之一是使用include加载列表,另一种是基本CRUD。

然而,我一直在讨论使用内存中数据库还是嘲笑ef核心数据库和数据库集?在单元测试中,用CRUD操作测试MVC EF Core Repository模式的最佳方式是什么?

public DbSet<ResourceTags>? ResourceTags { get; set; }
public class ResourceTags
{
[ForeignKey(nameof(ResourceRequest))]
[Key]
[Column(Order = 0)]
public byte[] ResourceId { get; set; }
[Key]
[Column(Order = 1)]
public string Tag { get; set; }
public ResourceRequest ResourceRequest { get; set; }
}
public ResourceTags? AddResourceTags(ResourceTags resourceTag)
{
try
{
var entity = this.prismContext.ResourceTags;
if (entity != null)
{
var response = entity.Add(resourceTag);
this.prismContext.SaveChanges();
return response.Entity;
}
}
catch
{
throw new Exception();
}
return null;
}
[TestMethod]
public void AddResourceTagsSavesAResourceTagsViaContext()
{
Random rnd = new Random();
var id = new byte[32];
rnd.NextBytes(id);
var text = "tagtext";
string convertedId = Convert.ToBase64String(id);
var mockResourceTag = new Mock<DbSet<ResourceTags>>();
var mockPrismContext = new Mock<PrismContext>();
mockPrismContext.Setup(m => m.ResourceTags).Returns(mockResourceTag.Object);
var azureRepository = new AzureRepository(mockPrismContext.Object);
var tag = new ResourceTags()
{
ResourceId = id,
Tag = text,
};
var response = azureRepository.AddResourceTags(tag);
Assert.IsNotNull(response);
}

如果您只使用简单的CRUD查询,并且您的查询不依赖于特定的DB函数,例如EF.Functions,那么您应该在内存模式下使用InMemory DatabaseSQLite,这与真实的DB具有更好的兼容性。

模拟DbSet会导致测试不佳,因为您的测试可能会通过,但当EF试图在运行时将您的LINQ查询转换为SQL时,它可能会引发异常,并且您希望确保您的转换有效。

第三种选择是针对docker容器进行测试,即,如果使用SQL Server,则针对在docker中运行的SQL Server实例进行测试。这样可以消除数据库之间的任何兼容性问题。

来源:

  • 测试EF核心应用程序
  • 针对生产数据库系统进行测试

最新更新