如何依赖于一个工厂
简答单元测试代码:你不。
Abstract Factories are a code smell
紧密耦合的代码是难以测试。 (但并非不可能)。
通过构造函数注入重构你的代码以显式依赖。 (避免服务定位器反模式)
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;
}
}
}
我不想让UI代码与的UnitOfWork打扰我只是想它来调用DataService类,让它做休息。
然后抽象服务,注入到用户界面,让它做剩下的。 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核心)
services.AddTransient<IUnitOfWork>(_ => UnitOfWorkFactory.CreateUnitOfWork());
services.AddTransient<ILessonDataService, LessonDataService>();
使用静态工厂往往会使他们的依赖项孤立测试比他们需要更困难。你是正确的,因为UI不应该关注UOW。但它与数据服务有关。 – Nkosi
你可以在'UnitOfWorkFactory'中注入一些依赖吗? – doctorlove