我需要快速开始测试我的业务层上的方法。考虑 Materials BLL 对象,我如何测试 AddNewMaterial 方法呢?
interface IGenericRepository<TEntity>
{
TEntity Add(TEntity m);
}
public interface IMaterialRepository : IGenericRepository<Material>
{
}
public interface IUnitOfWork
{
IMaterialRepository Materials { get; private set;}
void Save();
}
public interface IUnitOfWorkFactory
{
IUnitOfWork GetUnitOfWOrk();
}
public class MaterialsBLL
{
private readonly IUnitOfWorkFactory _uowFactory;
//uowFactory comes from DI
public MaterialsBLL(IUnitOfWorkFactory uowFactory)
{
_uowFactory = uowFactory;
}
//TODO: test this
public Material AddNewMaterial(Material m)
{
using(var uow = _uowFactory.GetUnitOfWOrk())
{
var result = uow.Materials.Add(m);
uow.Save();
return result;
}
}
我正在使用 Moq 和 XUnit,但我很环保。一般来说,我想这样做:
- 模拟存储库的 Add 方法。
- 模拟 UoW Materials 属性以返回我的存储库模拟。
- 模拟 UoWFactory 以返回 UoW 模拟。
- 创建 MaterialsBLL,将模拟的 UoWFactory 提供给构造函数。
- 验证 AddNewMaterials 调用存储库的 Add,以及 UoW 的 Save 等。
在我看来,我也许应该创建一个 Fake MaterialRepository,而不是嘲笑它?还有什么建议吗?这是第一次破解:
[Fact]
public void TestGetMaterialById()
{
var materialList = GetMaterials();
var materialRepositoryMock = new Mock<IMaterialRepository>();
materialRepositoryMock.Setup(repo => repo.Get(4)).Returns(materialList.First());
var uowMock = new Mock<IUnitOfWork>();
uowMock.SetupProperty<IMaterialRepository>(uow => uow.Materials, materialRepositoryMock.Object);
var uowFactoryMock = new Mock<IUnitOfWorkFactory>();
uowFactoryMock.Setup(f => f.GetUnitOfWork()).Returns(uowMock.Object);
var materialsBll = new Materials(uowFactoryMock.Object);
var result = materialsBll.Get(4);
Assert.Equal(result.MaterialId, 4);
Assert.Equal(result.Name, "Four");
}