使用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;
}
方法im测试
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语句中,则可能会出现这种情况。如果您正在使用依赖项注入,则应该让依赖项注入容器负责处理上下文实例。
在模拟中,createContext
方法是用dbcontext
的实例模拟的。对于所有对createContext
的调用,模拟返回相同的实例。您可以使用以下测试进行检查:
var context = CreateInMemoryContactContext();
var contextFactoryMock = new Mock<IContextFactory>();
contextFactoryMock.Setup(x => x.CreateContext()).Returns(context);
Assert.ReferenceEquals(context, contextFactoryMock.Object.CreateContext());
在thinkaddcontact
中处理上下文。当您重用上下文来执行断言时,上下文将被释放。
您需要在returns
中传递工厂,如下所示:
var contextFactoryMock = new Mock<IContextFactory>();
contextFactoryMock.Setup(x => x.CreateContext()).Returns(CreateInMemoryContactContext);
为了在上下文之间保存数据,需要在创建新的dbcontext时重用相同的DbOption。使用xunit,对于每个测试,都会实例化一个测试类的实例。您可以将初始化部分放在构造函数中:
public class AddContactTest
{
private DbOptions _dbOptions;
public AddContactTest()
{
_options = new DbContextOptionsBuilder<ContactContext>().UseInMemoryDatabase((Guid.NewGuid().ToString())).Options
}
private ContactContext CreateInMemoryContactContext()
{
var _inMemoryContext = new ContactContext(_dbOptions);
return _inMemoryContext;
}
[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();
}
}
}
您正在处理正在测试的方法中的上下文,这样您就不能再使用它了。解决这一问题的方法之一是创建一个新上下文,但您需要手动跟踪InMemoryDatabaseRoot
实例。例如:
private static readonly _memoryDatabaseRoot InMemoryDatabaseRoot = new InMemoryDatabaseRoot();
private ContactContext CreateInMemoryContactContext()
{
var _inMemoryContext = new ContactContext(new DbContextOptionsBuilder<ContactContext>()
.UseInMemoryDatabase("my-database", _memoryDatabaseRoot).Options);
return _inMemoryContext;
}
现在,在测试中,您可以调用CreateInMemoryContactContext
来获取使用相同内存中数据库实例的新上下文
注意:如果要在多个测试中使用根,您可能不希望它是静态的。
问题内容: 我希望在编写用于测试某些数据库条目的单元测试中获得一些建议。 如果找不到记录,则我正在测试的功能会将数据库作为种子。 我似乎不太了解如何进行len测试。我正在使用测试数据库,因此我可以在任何时候都对其进行核对,因此,如果我只需要在函数上强制使用一个空的数据库,就没有问题了。 该函数本身可以正常工作,我只想确保已覆盖该函数。 任何建议都很好。 谢谢! 问题答案: 确实取决于您,有很多方法
我是spring的新手,目前我正在尝试为我的项目执行单元测试。我已经用hibernate配置了spring,现在我想检查创建的类的方法是否工作。例如,假设我有: 如何正确测试这些方法?最好的选择是什么?我习惯在JUnit测试中使用assertTrue和assertFalse,但我担心这在我的情况下不是一个好的选择。谢谢你。
问题内容: 我做了一个简单的测试用例: 并且我希望测试能够通过,但是我遇到了异常: 我以为assertRaises将通过,因为将引发TypeError异常? 问题答案: 如果您使用的是python2.7或更高版本,则可以将assertRaises用作上下文管理器并执行以下操作: 如果您正在使用python2.6,那么到目前为止,还有另一种方法是使用unittest2,这是unittest新功能到p
当你想要使用接近真实数据库的东西来测试组件,同时又不想造成实际数据库输入输出的操作开销时,内存(InMemory)提供程序会很有用。 提示 你可以在 GitHub 上查阅当前文章涉及的代码样例。 InMemory 不是关系数据库 EF Core 数据库提供程序并非就是关系数据库。InMemory 是设计用于测试的通用数据库,而不是模拟关系数据库。 与此相关的样例包括: InMemory将允许您保存
我正在尝试使用测试驱动设计方法编写一个应用程序--我对单元测试很陌生,所以我只是想知道测试正确输入和异常的正确方法是什么。 我有一个用于加载配置文件的类: null 另外,这3个测试是否都有try{}catch(){}语句?在第一个测试中,正确性是隐含的,在第二个和第三个测试中,我无论如何都在检查异常,所以异常对测试没有影响。
当管理员在结束视图中按下“conlude”按钮时,我希望程序遍历数据库中的每条记录,并检查是否正好有2条记录(不多不少)将候选设置为true。(Rest会是假的)。我以为我可以通过计数循环来实现这一点,该循环遍历每个记录并检查候选是否设置为true或false,但是我如何在ASP.NET MVC中实现这一点?? 谢谢你抽出时间 存储过程 行动/方法