一次性方法的单元测试
单元测试有问题。 我有一个standart Reprository和UnitOfWork模式。 例如,我有一个的UnitOfWork类:程序女巫的另一部分用于一次性方法的单元测试
public class UnitOfWork : IDisposable
{
private readonly MyDbContext _context;
... repositories
private IMyEntityRepository _myEntityRepository;
...
}
UnitOfWok作出一些特殊的操作与实体。例如,有一种方法,使用whitch的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;
}
}
我的问题是如何编写单元测试的MyMethod如果有农业综合整治开发using(_unitOfWork = new UnitOfWork)
?在这种情况下,我怎样才能使用伪造的UnitOfWork和Fake上下文?感谢您的任何建议。
为了让您的课程更具仿造性和可测试性,我建议尽可能抽象您的UnitOfWork
和Repositories
,然后使用工厂将它们注入依赖它们的类中。
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;
}
}
}
现在,您可以模拟/伪造您的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());
}
上面显示了如何使用上述框架轻松测试所有内容。
希望这可以帮助
非常感谢你的详细解答。 – user3609841
你有一个工厂的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())
{
//..
}
}
}
请注意,类需要一个Func<UnitOfWork>
代替UnitOfWork
的,因为我假设您希望每次致电MyMethod
都有一个新实例UnitOfWork
。
在你的测试,您可以创建一个假UnitOfWork
,然后你可以将它传递给这样的MyClass
实例:
var sut = new MyClass(() => fakeInstance);
你还需要确保UnitOfWork
是fakeable。例如,因为它是一个具体的类,所以你需要确保相关的方法是virtual
。另一种方法是有一个接口IUnitOfWork
是UnitOfWork
工具和MyClass
用途。
通过没有在UoW类中实例化上下文,而是提供它作为(构造函数)依赖项。 – spender