使用 Repository 和 UnitOfWork 模拟删除

Mocking A Delete using Repository and UnitOfWork

使用 Unit,我正在尝试设置一个测试,我可以从我的 Mock 列表中删除一个条目,以便测试我的 CustomerManager 中的实现。

我的资料库:

public class Repository<T> : IRepository<T> where T : ModelBase
{
    private readonly CustomerDbContext _context;

    public Repository(CustomerDbContext context)
    {
        if (_context == null)
            throw new ArgumentNullException(nameof(context));
        _context = context;
    }

    public async Task Delete(int id, bool softDelete = true)
    {
        var entity = await GetById(id);
        if (entity == null) return;

        if (softDelete)
        {
            entity.IsDeleted = true;
            Save(entity);
        }
        else
            _context.Set<T>().Remove(entity);
    }

    public async Task<T> GetById(int id)
    {
        return await _context.Set<T>().FirstOrDefaultAsync(t => t.Id == id).ConfigureAwait(false);
    }

    public void Save(T entity)
    {
        if (entity.Id == 0)
            _context.Set<T>().Add(entity);
        else
            _context.Entry(entity).State = EntityState.Modified;
    }
}

我的工作单位是:

public class CustomerUnitOfWork : IUnitOfWork
{
    public CustomerDbContext Context { get; }

    public async Task<int> Commit()
    {
        foreach(var item in Context.ChangeTracker.Entries().Where(e => e.State == EntityState.Added || e.State == EntityState.Modified))
        {
            if (!(item.Entity is ModelBase entity))
                continue;
            if (item.State == EntityState.Added)
            {
                entity.CreatedDate = DateTime.UtcNow;
            }
            entity.ModifiedDate = DateTime.UtcNow;                
        }
        return await Context.SaveChangesAsync();
    }
}

我的经理是:

public class CustomerManager : ICustomerManager
{
    private readonly IRepository<Models.Customer> _customerRepository;
    protected readonly IUnitOfWork _unitOfWork;

    public CustomerManager(IRepository<Models.Customer> customerRepository, IUnitOfWork unitOfWork)
    {
        _customerRepository = customerRepository;
        _unitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork));
    }

    public async Task<int> Delete(int id, bool softDelete = true)
    {
        await _customerRepository.Delete(id, softDelete);
        return await _unitOfWork.Commit();
    }

    public async Task<Models.Customer> GetById(int id)
    {
        return await _customerRepository.GetById(id);
    }
}

在我的单元测试中,我像这样设置构造函数:

private ICustomerManager MockManager;
private Mock<IUnitOfWork> UnitOfWork;
private List<Models.Customer> Customers;
Mock<IRepository<Models.Customer>> MockRepository;

public CustomerTest()
{
    MockRepository = new Mock<IRepository<Models.Customer>>();
    UnitOfWork = new Mock<IUnitOfWork>();
    Customers = new List<Models.Customer>()
    {
        new Models.Customer
        {
            Id = 1,
            Name = "Foo",
            City = "Baltimore",
            Company = "Foo Company"
        },
        new Models.Customer
        {
            Id = 2,
            Name = "Bar",
            City = "Owings Mills",
            Company = "Bar Company"
        }
    };
    MockRepository.Setup(repo => repo.GetAll()).ReturnsAsync(Customers);
    MockRepository.Setup(repo => repo.GetById(It.IsAny<int>())).ReturnsAsync((int i) => Customers.SingleOrDefault(c => c.Id == i));
    MockRepository.SetupAllProperties();
    MockManager = new CustomerManager(MockRepository.Object, UnitOfWork.Object);

}

在我的测试方法中,我想删除测试列表中的第一个对象。

public async Task ShouldDelete()
{
    var countBeforeDelete = Customers.Count();
    var countAfterDelete = await MockManager.Delete(1, true);
    Assert.Equal(countBeforeDelete, countAfterDelete);
}

但是,CountAfterDelete总是returns0。我不确定我做错了什么。

您经理的 Delete 方法 returns await _unitOfWork.Commit();

默认情况下,IUnitOfWork 的 Mock 将 return default(int) 为 0。