我正在开发一个使用实体FrameworkCore2.0的ASP.Net Core2.0API。我试图使用XUnit和Moq构建单元测试,但在为DbContext创建接口时遇到了问题,以便在单元测试中模拟它。
目前,我的项目没有为我的上下文使用接口。我将它作为其实现注入到存储库类中。在我的Startup.cs中,我使用services.AddDbContext来设置它。
典型存储库类构造函数的示例。
public CompaniesRepository(MyDbContext myDbContext)
{
_myDbContext = myDbContext;
}Startup.cs实例
services.AddDbContext<MyDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("MyDbConnectionString"),
sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(5,TimeSpan.FromSeconds(30),sqlTransientErrors);
});
});这种方法一直运作得很好。
然而,现在我正在尝试设置单元测试,我希望能够伪装我的上下文,所以我需要为它创建一个接口。
因此,我向MyDbContext添加了一个名为IMyDbContext的接口,并在Startup.cs中添加了以下代码,如下所示
services.AddScoped<IMyDbContext>(provider => provider.GetService<MyDbContext>());似乎起作用了,除了一个问题。我还使用Boris的EFCore.BulkExtensions NuGet,因此,我从存储库类中得到一个编译错误,它现在将IMyDbContext接口注入构造函数中,声明我的接口不包含BulkInsert的定义。
Error CS1929 'IMyDbContext‘不包含'BulkInsert’的定义,最好的扩展方法重载BulkInsert IList、BulkConfig、Action)‘需要一个'DbContext’类型的接收方。
我假设我需要以某种方式将BulkInsert扩展方法添加到我的IMyDyBontext接口中,但我不知道如何正确地做到这一点。如果我只是尝试将该方法添加到我的接口中,那么我就会发现一个错误,它不是在我的MyDbContext类中实现的。
如何在我的BulkInsert类中引用MyDbContext扩展方法?
发布于 2018-05-13 19:02:51
BulkInsert是一种扩展方法。您不能轻松地模拟静态方法。
相反,您可以在MyDbContext类中实现它。然后,您可以模拟IMyDbContext进行单元测试。注:我没有测试它。
public interface IMyDbContext
{
void BulkInsert<T>(IList<T> entities, BulkConfig bulkConfig = null,
Action<decimal> progress = null) where T : class;
}
public class MyDbContext : DbContext, IMyDbContext
{
public void BulkInsert<T>(IList<T> entities, BulkConfig bulkConfig = null,
Action<decimal> progress = null) where T : class
{
this.BulkInsertOrUpdate(entities, bulkConfig, progress);
}
}发布于 2019-03-18 19:32:41
最近,我在准备在使用EF包时模拟我的DbContext进行单元测试时遇到了这个问题。标记为正确答案的响应是,几乎是正确的(尽管他们确实说没有测试他们的代码)。
当以上述方式在DbContext类中实现这一功能时,您将在调用BulkInsert方法时收到一个BulkInsert。
因此,我开始调试,并决定在DbContext类中的方法上放置一个断点,以查看发生了什么。这使我理解了StackOverflowException的原因:由于" This“关键字的范围,该方法正在调用自身而不是基类DbContext类上的方法。
解决方案相当简单,通过对BulkInsert实现中的MyDbContext方法实现进行以下更改来解决:
public async Task BulkInsertAsync<T>(IList<T> entities, BulkConfig bulkConfig = null, Action<decimal> progress = null) where T : class
{
await ((DbContext)this).BulkInsertAsync<T>(entities, bulkConfig, progress);
}另外,将以下行添加到您的IMyDbContext接口:
Task BulkInsertAsync<T>(IList<T> entities, BulkConfig bulkConfig = null, Action<decimal> progress = null) where T : class;这确保了将" This“的范围转换为基本的DbContext类类型,而不是我自己的DbContext实现的类型。因此,它没有调用自己,而是使用基类DbContext调用扩展方法。
使用此解决方案,您现在应该能够在代码中成功地使用扩展方法,如下所示:
await _context.BulkInsertAsync<User>(users);希望有人能找到有用的东西。通过调试解决这个问题并不是太糟糕,并且确保了在使用BulkExtensions包时,我可以轻松地保持所有方法的可测试性!
https://stackoverflow.com/questions/50318941
复制相似问题