Net Core:使用Xunit对工作单元模式和DBContext执行依赖注入

时间:2019-08-29 19:27:29

标签: c# .net asp.net-core .net-core xunit

我正在尝试对具有工作单元模式的基本存储库进行依赖注入,我们使用的是通用存储库(由公司架构师决定)。

出于某种原因,什么都没有节省,只是想知道在下面的依赖项注入中将DBContext与工作单元相关联的正确方法是什么。目前在测试时,下面收到的空值,在Entity Framework中没有任何保存。

它可以使用常规Dbcontext保存,但是测试后不能使用工作单位模式保存值。

在Xunit test.cs中,似乎我需要将TestContext作为参数传递给UnitofWork构造函数,不确定如何在依赖注入中接收错误,

工作单元

public class UnitOfWork : IUnitOfWork
{
    private readonly DbContext context;
    public UnitOfWork(DbContext context)
    {
        this.context = context;
    }

    public DbSet<TEntity> DBSet<TEntity, TPrimaryKey>() where TEntity : class, IEntity<TPrimaryKey> => context.Set<TEntity>();

    public void SetAsModified<TPrimaryKey>(IEntity<TPrimaryKey> entity) => Task.Run(() => context.Entry(entity).State = EntityState.Modified);

    public async Task Save()
    {
        await context.SaveChangesAsync();
    }

    // IDisposable pattern support
    private bool disposed = false;
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed && disposing)
        {
            context.Dispose();
        }
        this.disposed = true;
    }

基本存储库:

public class BaseRepository<T, TPrimaryKey> : IRepository<T, TPrimaryKey> where T : class, IEntity<TPrimaryKey>
{
    private readonly IUnitOfWork unitOfWork;
    protected virtual DbSet<T> DbSet { get; }
    protected IQueryable<T> All => DbSet.AsNoTracking();

    public IUnitOfWork UnitOfWork => unitOfWork;

    public BaseRepository(IUnitOfWork unitOfWork)
    {
        this.unitOfWork = unitOfWork;
        DbSet = unitOfWork.DBSet<T, TPrimaryKey>();
    }

    public void Insert(T entity)
    {
        DbSet.Add(entity);
    }

    public IQueryable<T> GetAll()
    {
        return All;
    }

public class BaseRepository<T> : BaseRepository<T, int>, IRepository<T> where T : class
{
    public BaseRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
    {

    }
}

XUnit测试:

    var services = new ServiceCollection();
    services.AddDbContext<TestContext>(a => a.UseInMemoryDatabase("Test"));
    services.AddTransient<DbContext, TestContext>();
    services.AddTransient<IUnitOfWork, UnitOfWork>();
    services.AddTransient(typeof(IRepository<>), typeof(BaseRepository<>));
    ServiceProvider serviceProvider = services.BuildServiceProvider();
    var scope = serviceProvider.CreateScope();

    var testdbContext = scope.ServiceProvider.GetServices<TestContext>();
    var unitOfWork = scope.ServiceProvider.GetService<IUnitOfWork>();

    var ProductRepository = scope.ServiceProvider.GetService<IRepository<Product>>();


    ProductRepository.Insert(new Product {ProductId = 1, ProductName = "ABC";
    ProductRepository.Insert(new Product {ProductId = 2, ProductName = "DEF");
    await unitOfWork.Save();


    public Product()
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription{ get; set; }
    }

什么都没有保存。在调试期间-我将DBSet中的值设置为绿色,但进行ProductRepository.GetAll()时并不能全部设置,试图弄清楚

enter image description here

更新

仅使用DbContext保存时,它可以工作。 但是,不能使用工作单位进行保存。

TestContext.Product.Add(expectedResult[0]);
TestContext.Product.Add(expectedResult[1]);
TestContext.SaveChanges();

参考问题: Net Core: Execute All Dependency Injection in Xunit Test for AppService, Repository, etc

1 个答案:

答案 0 :(得分:2)

您正在将服务注册为临时服务,这意味着DI容器每次需要解析或注入服务时都会创建新的实例,因此被注入到IUnitOfWork中的IRepository<>实例是'与GetService<IUnitOfWork>()相同。您可以通过向services.AddScoped注册服务来解决此问题,这样将为每个打开的作用域创建每个服务的单个实例。