如何依賴於一個工廠
簡答單元測試代碼:你不。
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