如何模拟DbContext在存储库的单元测试中使用?

时间:2020-05-22 11:04:23

标签: c# asp.net entity-framework entity-framework-core moq

我有一个存储库,其中包含一个我想编写测试的公共方法。但是,要实例化存储库,我需要为其提供一个DbContext对象。

随着我不断回来,尝试模拟这个DbContext非常困难

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.ArgumentNullException: Value cannot be null. (Parameter 'databaseFacade')
   at Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T](T value, String parameterName)
   at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.GetRelationalService[TService](IInfrastructure`1 databaseFacade)
   at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.SetCommandTimeout(DatabaseFacade databaseFacade, Nullable`1 timeout)
   at sw.cldflt.policymanager.api.UserDbContext..ctor(DbContextOptions`1 options) in C:\source\sw-cldflt-azr-policymanagement\sw-cldflt-policymanagement-api\sw.cldflt.policymanager.api\UserDbContext.cs:line 11
   at Castle.Proxies.UserDbContextProxy..ctor(IInterceptor[] , DbContextOptions`1 options)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Activator.CreateInstance(Type type, Object[] args)
   at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments)
   at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
   at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments)
   at Moq.Mock`1.InitializeInstance()
   at Moq.Mock`1.OnGetObject()
   at Moq.Mock.get_Object()
   at Moq.Mock`1.get_Object()

我正在尝试编写一种设置方法,以实例化存储库供我在测试方法中使用,设置方法如下。

[TestInitialize]
    public void Setup()
    {
        // DbContextOptions options = new DbContextOptions();
        var options = new DbContextOptionsBuilder<UserDbContext>()
            .UseInMemoryDatabase(databaseName: "Test")
            .Options;
        _userDataRepository = new UserDataRepository(_userDbContext);    

    }

我该怎么做才能使我回购该仓库?

public UserDataRepository(UserDbContext dbContext)
        {
            _dbContext = dbContext;
        }


public class UserDbContext : DbContext
    {
        public UserDbContext(DbContextOptions<UserDbContext> options) : base(options)
        {
            Database.SetCommandTimeout((int)TimeSpan.FromMinutes(3).TotalSeconds);
        }
        public DbSet<User> Users { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>().ToTable("Users").HasKey(e => e.Id);
            base.OnModelCreating(modelBuilder);
        }
    }

1 个答案:

答案 0 :(得分:0)

Entity Framework Core为此提供了InMemory数据存储。 您需要在单元测试项目中添加对Microsoft.EntityFrameworkCore.InMemory的引用,然后将其配置为使用InMemoryProvider。请在官方网站上查看此链接:https://entityframeworkcore.com/providers-inmemory