我在单元测试方面遇到了问题。 我有一个标准的 Reprository 和 UnitOfWork 模式。 例如,我有一个 UnitOfWork 类:
public class UnitOfWork : IDisposable
{
private readonly MyDbContext _context;
... repositories
private IMyEntityRepository _myEntityRepository;
...
}
UnitOfWok 在程序的另一部分中使用,对实体进行一些特殊操作。例如,有一个使用 UnitOfWork 的方法:
public IEnumerable<MyClass> MyMethod()
{
using (_unitOfWork = new UnitOfWork())
{
var myEntities= _unitOfWork.MyEntityRepository.Get();
var result = ... some logic to convert myEntities collection to IEnumerable<MyClass>
return result;
}
}
我的问题是,如果存在构造using(_unitOfWork = new UnitOfWork)
,如何为 MyMethod 编写单元测试?在那种情况下,我怎么能将假的 UnitOfWork 与假的上下文一起使用呢?感谢您的任何建议。
最佳答案
为了使您的类更易于伪造和测试,我建议尽可能抽象您的 UnitOfWork
和 Repositories
,然后使用工厂将它们注入(inject)到依赖的类中在他们身上。
public interface IUnitOfWork : IDisposable {
... repositories
IMyEntityRepository MyEntityRepository;
...
}
你的 UnitOfWork
将从该接口(interface)派生
public class UnitOfWork : IUnitOfWork {...}
IUnitOfWorkFactory
public interface IUnitOfWorkFactory {
IUnitOfWork Create();
}
有了它,依赖类就可以看起来像这样
public class MyDependentClass {
private readonly IUnitOfWorkFactory unitOfWorkFactory;
public MyDependentClass (IUnitOfWorkFactory unitOfWorkFactory) {
this.unitOfWorkFactory = unitOfWorkFactory;
}
public IEnumerable<MyClass> MyMethod() {
using (var _unitOfWork = unitOfWorkFactory.Create()) {
var myEntities= _unitOfWork.MyEntityRepository.Get();
var result = ... some logic to convert myEntities collection to IEnumerable<MyClass>
return result;
}
}
}
现在您可以模拟/伪造您的 UnitOfWork
和 Repositories
而无需伪造上下文。
假设您想测试/验证 UOW 在调用 MyMethod
之后是否实际被处理掉
(我使用 Moq
和 FluentAssert
进行演示)
您可以按如下方式构建测试:
[TestMethod]
public void UOW_Should_Be_Disposed() {
//Assert
var fake_entities = Enumerable.Range(1, 10).Select(i => new MyEntity());
var mockRepository = new Mock<IMyEntityRepository>();
mockRepository.Setup(m => m.Get()).Returns(fake_entities);
var mockUOW = new Mock<IUnitOfWork>();
mockUOW.Setup(m => m.MyEntityRepository).Returns(mockRepository.Object);
var mockFactory = new Mock<IUnitOfWorkFactory>();
mockFactory.Setup(m => m.Create()).Returns(mockUOW.Object);
//Act
var sut = new MyDependentClass(mockFactory.Object);
var output = sut.MyMethod().ToList();
//Assert
output.Should().NotBeNull();
output.Should().HaveCount(10);
output.Should().ContainItemsAssignableTo<MyClass>();
mockUOW.Verify(m => m.Dispose());
}
上面显示了如何使用提到的框架轻松测试所有内容。
希望对你有帮助
关于c# - 一次性方法的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36635068/