xUnit,Moq与UnitOfWork和通用存储库



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

GeneralRepository.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; }
...
}

UnitOfWork.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
???
}
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);

最新更新