blazor mocking IDbContextFactory



我正在尝试对Blazor项目的服务器API进行单元测试

因此,我有这个构造器为我的API接收工厂

public MyThingApi(IDbContextFactory<MyDbContext> factory)
{
this.factory = factory;
}

然后我有这个功能来获得我的东西列表:

public async Task<List<MyThing>> GetMyThingsAsync()
{
using var context = factory.CreateDbContext();
return await context.MyThings.ToListAsync();
}

现在,如果我想使用Moq测试GetMyThingsAsync,我必须模拟工厂。但模拟代码看起来像:

Mock<IDbContextFactory<MyDbContext>>

这就是我不明白的:MyDbContext不是一个接口。因此,在代码中CreateDbContext将始终返回一个MyDbContext。所以我不能嘲笑它,它将是";真实的";上下文中有一个";真实的";数据库连接。上下文也是如此。MyThings将从数据库中检索它。

那么,当上下文由工厂生成时,模拟上下文的魔力是什么呢?

这个答案使用内存数据库,这使得整个模拟非常简单。

步骤1:

在单元测试项目中安装这些nuget包:

  1. Microsoft.EntityFrameworkCore.IMemory
  2. Moq
  3. xunit
  4. Shouldly

步骤2:

这样设置测试:

using Moq;
using Shouldly;
using Microsoft.EntityFrameworkCore;
namespace YourProject.UnitTests;
public class YourTests
{
[Fact]
public async Task Should_Get_My_ThingsAsync()
{
// ARRANGE
var mockDbFactory = new Mock<IDbContextFactory<MyDbContext>>();
var options = new DbContextOptionsBuilder<MyDbContext>()
.UseInMemoryDatabase(databaseName: "SomeDatabaseInMemory")
.Options;
// Insert seed data into the database using an instance of the context
using (var context = new MyDbContext(options))
{
context.MyThings.Add(new MyThing { Id = 1, SomeProp = "Some Prop Value" });
context.MyThings.Add(new MyThing { Id = 2, SomeProp = "Some Prop Value" });
context.SaveChanges();
}
// Now the in-memory db already has data, we don't have to seed everytime the factory returns the new DbContext:
mockDbFactory.Setup(f => f.CreateDbContextAsync(It.IsAny<CancellationToken>())).ReturnsAsync(() => new MyDbContext(options));
// ACT
var myThingApi = new MyThingApi(mockDbFactory.Object);
var result = await myThingApi.GetMyThingsAsync();
// ASSERT
result.ShouldNotBeNull();
result.Count.ShouldBe(2);
// other asserts
}
}

我使用内存中的sqlite数据库进行测试。

相关内容

  • 没有找到相关文章

最新更新