模拟实体框架核心上下文

bie*_*000 7 c# entity-framework entity-framework-core asp.net-core

我尝试测试我的应用程序,所以我需要模拟我的EF上下文.

我的代码似乎没问题,但我有以下异常:

"System.ArgumentNullException:Value不能为null.参数名称:source"

这是我的测试方法:

  var options = new DbContextOptionsBuilder<ProductContext>().Options;
    var settings = new SqlSettings
    {
        InMemory = true
    };

    var context = new Mock<ProductContext>(options, settings);
    var mockTreeService = new TreeService(context.Object);
    await mockTreeService.CreateTreeAsync("Testing tree", Guid.NewGuid());

    context.Verify(x => x.AddAsync(It.IsAny<Tree>(), CancellationToken.None), Times.Once);
Run Code Online (Sandbox Code Playgroud)

看起来在执行这段代码时抛出了这个expceiton

            var tree = await _context.Trees
                .Include(x => x.Translation)
                .FirstOrDefaultAsync(x => x.Translation.Pl == name);
Run Code Online (Sandbox Code Playgroud)

它来自我正在测试的服务

Chr*_*att 23

我认为这是由于没有设置连接字符串.坦率地说,完全模拟出来有点困难DbContext,这就是EF Core团队提供内存实现的原因.这对于测试目的而言更容易使用.只需将options初始化更改为:

var options = new DbContextOptionsBuilder<ProductContext>()
                  .UseInMemoryDatabase(Guid.NewGuid().ToString())
                  .Options;
Run Code Online (Sandbox Code Playgroud)

之后,您需要使用测试数据填充数据库.然后,您可以运行其余的测试.

注意:如果您正在使用内存数据库,则不需要再模拟上下文,因此您可以删除该位代码.内存数据库本身就是一个模拟.

  • 必须在我的测试项目中包含对 Microsoft.EntityFrameworkCore.InMemory 的引用! (3认同)

cde*_*dev 5

我已经使用了这个https://github.com/huysentruitw/entity-framework-core-mock库。非常简单,可以使用较少的编码编写单元测试。

如果您使用的是 moq 框架,则可以使用大多数 Moq 方法。

下面是测试 DBQuery 的示例代码。

public async Task<Boat> GetByIdAsync(string id)
    => await _boatContext.Boats.Where(x => x.id == id).FirstOrDefaultAsync();

[Fact]
public async Task GetByIdAsync_WhenCalled_ReturnsItem()
{
    // Arrange
    var models = new[] { new Boat { id = "p1" } };
    var dbContextMock = new DbContextMock<BoatContext>();
    dbContextMock.CreateDbQueryMock(x => x.Boats, models);

    var service = new Properties(dbContextMock.Object);

    // Act
    var okResult = await service.GetByIdAsync("p1");

    // Assert
    Assert.IsType<Boat>(okResult.Result);
}
Run Code Online (Sandbox Code Playgroud)

在这里发布这可能对某人有所帮助:)