代码之家  ›  专栏  ›  技术社区  ›  sada

xUnit,Moq,带UnitOfWork和通用存储库

  •  0
  • sada  · 技术社区  · 4 年前

    我试了很多例子,但没有得到很好的回应。 ReportUpload方法基于ExcelManager列表中的列表创建一些报表实体 并将它们添加到报表数据库集中。 我的目标是从模拟的DbSet中读取添加的实体并断言它们。 请问我如何将模拟的DbContext和Dbset传递到UnitOfWork?

    通用存储库.cs

    public class GeneralRepository<TContext, TEntity> : IGeneralRepository<TEntity>
        where TEntity : class
        where TContext : DbContext
    {
        protected readonly TContext _context;
        protected readonly DbSet<TEntity> dbSet;
    
        public GeneralRepository(TContext context)
        {
            _context = context;
            dbSet = _context.Set<TEntity>();
        }
    
        public async Task AddAsync(TEntity entity)
        {
            await _context.Set<TEntity>().AddAsync(entity);
        }
        ...
    }
    

    IUnitOfWork.cs

    public interface IUnitOfWork : IDisposable
    {
        IGeneralRepository<Report> Reports{ get; }
        ...
    }
    

    工作单位.cs

    public sealed class UnitOfWork : IUnitOfWork
    {
        private readonly MyDbContext _context;
    
        public UnitOfWork(MyDbContext context)
        {
            _context = context;
        }
    
        private IGeneralRepository<Report>_report;
        public IGeneralRepository<Report> Reports => _report ??= new GeneralRepository<MyDbContext, Report>(_context);
        ...
    }
    

    ReportService.cs

    public class ReportService : GeneralService, IReportService
    {
        private readonly IExcelManager _excelManager;
    
        public ReportService(IUnitOfWork unitOfWork, IExcelManager excelManager)
        {
            UnitOfWork = unitOfWork;
            _excelManager = excelManager;
        }
    
        public async Task<string> ReportUpload(MemoryStream ms)
        {
            var workingList = _excelManager.ReadExcel(ms);
     
            var i = 0;             
            while (i < workingList.Count)
            {
                var report = new Report { ... }
                await UnitOfWork.Reports.AddAsync(report);
            }
    
            ....
    }
    

    ReportServiceTest.cs

    public class ReportServiceTests 
    {
        [Fact()]
        public async Task ReportUploadTest()
        {
    
            //Arrange
            ....
            var mockSet = new Mock<DbSet<Report>>();
            var mockContext = new Mock<MyDbContext>();
            mockContext.Setup(x => x.Reports).Returns(mockSet.Object);
    
            var reportRepositoryMock = new Mock<IGeneralRepository<Report>>();
            reportRepositoryMock.Setup(m => m.AddAsync(It.IsAny<Report>()));
    
            var unitOfWorkMock = new Mock<IUnitOfWork>();
            unitOfWorkMock.Setup(p => p.Reports)
                .Returns(reportRepositoryMock.Object);
    
           ...
           //Act
           var reportService = new ReportService(unitOfWorkMock.Object,exelManagerMock.Object);
           await reportService.ReportUpload(new MemoryStream());
    
           //Assert
           ???
     }
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   sada    4 年前

    DbContext不能传递给UnitOfWork对象,因为它的上下文字段是私有的。

    我不得不在内存中使用SQLite来测试GeneralRepository方法。

    var exelManagerMock = new Mock<IExcelManager>();
            exelManagerMock.Setup(p => p.ReadExcel(It.IsAny<MemoryStream>()))
                .Returns(listOfExcelReadResult);    
    var dbFixture = new DatabaseFixture();
    var context = dbFixture.CreateContext();
    
    var unitOfWork = new UnitOfWork(context);
    //I need some plus data  
    await unitOfWork.Providers.AddRangeAsync(providers);
    await context.SaveChangesAsync();
    
    var reportService = new ReportService(unitOfWork, exelManagerMock.Object);
    await reportService.ReportUpload(new MemoryStream(), 2021);
    
    var allReports = await reportService.UnitOfWork.Reports.GetAsync();
    Assert.Equal(3, allReports.Count);
    
    推荐文章