C# 一次性使用方法的单元试验
我对单元测试有问题。 我有一个标准的复述和单元工作模式。 例如,我有一个UnitOfWork类:C# 一次性使用方法的单元试验,c#,unit-testing,C#,Unit Testing,我对单元测试有问题。 我有一个标准的复述和单元工作模式。 例如,我有一个UnitOfWork类: public class UnitOfWork : IDisposable { private readonly MyDbContext _context; ... repositories private IMyEntityRepository _myEntityRepository; ... } UNITOWOK用于程序的另一个部分,它对实体进行一些特殊操作
public class UnitOfWork : IDisposable
{
private readonly MyDbContext _context;
... repositories
private IMyEntityRepository _myEntityRepository;
...
}
UNITOWOK用于程序的另一个部分,它对实体进行一些特殊操作。例如,有一种方法使用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;
}
}
public IEnumerable MyMethod()
{
使用(_unitOfWork=new unitOfWork())
{
var myEntities=_unitOfWork.MyEntityRepository.Get();
var result=…将myEntities集合转换为IEnumerable的一些逻辑
返回结果;
}
}
我的问题是,如果使用(_unitOfWork=newunitofwork)进行构造
,如何为MyMethod编写单元测试?在这种情况下,我如何使用假UnitOfWork和假上下文?谢谢您的建议。您必须通过构造函数注入将UnitOfWork
的工厂注入到包含MyMethod
方法的类中,如下所示:
public class MyClass
{
private readonly Func<UnitOfWork> unitOfWorkFactory;
public MyClass(Func<UnitOfWork> unitOfWorkFactory)
{
this.unitOfWorkFactory = unitOfWorkFactory;
}
public IEnumerable<MyClass> MyMethod()
{
using (unitOfWork = unitOfWorkFactory())
{
//..
}
}
}
var sut = new MyClass(() => fakeInstance);
您还需要确保UnitOfWork
是伪造的。例如,由于它是一个具体的类,因此需要确保相关的方法是virtual
。另一种方法是拥有一个接口IUnitOfWork
,该接口由UnitOfWork
实现,并由MyClass
使用。为了使类更易于伪造和测试,我建议尽可能抽象UnitOfWork
和存储库
,然后使用工厂将它们注入到依赖于它们的类
public interface IUnitOfWork : IDisposable {
... repositories
IMyEntityRepository MyEntityRepository;
...
}
您的UnitOfWork
将从该接口派生
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;
}
}
}
上面展示了如何使用上述框架轻松地测试所有内容
希望这有助于不要在UoW类中实例化上下文,而是将其作为(构造函数)依赖项提供。非常感谢mutch提供的详细答案。
[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());
}