【发布时间】:2021-03-24 14:30:18
【问题描述】:
使用InMemory 数据库我正在尝试编写一个单元测试,它将检查一个方法是否正在向表中添加一条记录。记录被添加到被测类中,但是当我尝试重新创建时,我得到了上下文处理错误。设置此测试的正确方法是什么,以便在处理上下文后检查内存中的表?
单元测试
[Fact]
public void Test_AddContact_AddsSuccessfully()
{
var contextFactoryMock = new Mock<IContextFactory>();
contextFactoryMock.Setup(x => x.CreateContext()).Returns(CreateInMemoryContactContext());
var classUnderTest = new AddContact(contextFactoryMock.Object);
var response = classUnderTest.Run(new UkContactUsDto());
using (var ctx = contextFactoryMock.Object.CreateContext())
{
var items = ctx.ContactUs.ToList(); //<--- Exception happens here due to ctx being disposed
}
}
创建 InMemory 方法
private ContactContext CreateInMemoryContactContext()
{
var _inMemoryContext = new ContactContext(new DbContextOptionsBuilder<ContactContext>().UseInMemoryDatabase((Guid.NewGuid().ToString())).Options);
return _inMemoryContext;
}
方法即时测试
try
{
await using var ctx = _contextFactory.CreateContext();
ctx.ContactUs.Add(contactUs);
ctx.SaveChanges();
}
catch (Exception ex)
{
log.LogInformation(ex,"An error occured during contact us insertion.");
throw;
}
错误信息
无法访问已释放的上下文实例。造成这种情况的一个常见原因 错误正在处理已解决的上下文实例 依赖注入,然后尝试使用相同的上下文 在您的应用程序的其他地方实例。如果您是 在上下文实例上调用“Dispose”,或将其包装在 using 陈述。如果你使用依赖注入,你应该让 依赖注入容器负责处理上下文 实例。
【问题讨论】:
-
我认为您的单元测试被测类将在这里使用不同的上下文。您的工厂将创建两个不同的上下文。我会先尝试生成一个上下文 (
using ctx = contextFactoryMock.Object.CreateContext()), then mock the factory with:contextFactoryMock.Setup(x => x.CreateContext()).Returns(ctx);` 然后检查添加的联系人,检查你的初始 ctx
标签: c# unit-testing entity-framework-core