我有一个如下所示的 DataService 类
public class LessonDataService
{
IUnitOfWork unitOfWork = UnitOfWorkFactory.CreateUnitOfWork();
public Lesson FindById(int id)
{
try
{
return unitOfWork.Lessons.FindById(id);
}
catch (Exception ex)
{
throw exception;
}
}
}
正如您所看到的,UnitOfWork 是在 DataService 类内部构造的。我也不希望通过构造函数传递 UnitOfWork,我不希望 UI 代码打扰 UnitOfWork,我只希望它调用 DataService 类并让它完成其余的工作。有什么想法吗?
最佳答案
How to unit test code that depends on a Factory
简短回答:你不。
Abstract Factories are a code smell
紧密耦合的代码很难测试。 (但并非不可能)。
通过构造函数注入(inject)重构代码以实现显式依赖。 (避免服务定位器反模式)
public class LessonDataService : ILessonDataService {
private readonly IUnitOfWork unitOfWork;
public LessonDataService(IUnitOfWork unitOfWork) {
this.unitOfWork = unitOfWork;
}
public Lesson FindById(int id) {
try {
return unitOfWork.Lessons.FindById(id);
} catch (Exception ex) {
throw exception;
}
}
}
I don't want the UI code to bother with UnitOfWork I just want it to call the DataService class and let it do the rest.
然后抽象服务,将其注入(inject)到 UI 中并让它完成其余的工作。 UI 不应直接与 UOW 相关。
public interface ILessonDataService {
Lesson FindById(int id);
}
通过重构以依赖于显式抽象,代码现在更加灵活,并且可以单独测试,并且负面影响最小。
[TestMethod]
public void DataService_Should_Get_Lesson() {
//Arrange
var id = 1;
var lesson = new Lesson {
Id = id,
//...code removed for brevity
};
var mock = new Mock<IUnitOfWork>();
mock.Setup(_ => _.Lessons.FindById(id)).Returns(lesson);
var sut = new LessonDataService(mock.Object);
//Act
var actual = sut.FindById(id);
//Assert
lession.Should().BeEquivalentTo(actual);
}
在生产代码中,当前工厂仍然可以在组合根中的 DI 容器中注册,但仍保持代码解耦。
例如(在.Net Core中)
services.AddTransient<IUnitOfWork>(_ => UnitOfWorkFactory.CreateUnitOfWork());
services.AddTransient<ILessonDataService, LessonDataService>();
关于c# - 如何对依赖于工厂的代码进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46428747/