Ваш текущий Anti-Pattern Service Locator - это то, что делает ваш код трудным для тестирования в отдельности, а также вводит класс в заблуждение относительно того, от чего он на самом деле зависит.
MainClass
следует реорганизовать, чтобы следовать Принцип явных зависимостей
public class MainClass : IMainClass
private readonly ILogger logger;
private readonly IDatabase db;
public MainClass(ILogger logger, IDatabase db) {
this.logger = logger;
this.db = db;
}
public void AddDetails(Data data) {
//do some business operations
db.Add(data);
logger.Information("added");
}
}
Аналогичный шаблон следует использовать и для любого другого вашего класса, который зависит от фабрики контейнеров, например Database
.
Однако вам также необходимо соответствующим образом изменить рефакторинг регистрации контейнера
public class ContainerInit {
public static IContainer BuildContainer() {
var builder = new ContainerBuilder();
builder.RegisterType<MainClass>().As<IMainClass>().SingleInstance();
builder.RegisterType<Database>().As<IDatabase>().SingleInstance();
var logger = LoggUtil.CreateLogger();
builder.Register(logger).As<ILogger>().SingleInstance();
var container = builder.Build();
return container;
}
}
Тестирование MainClass
потребовало бы, чтобы вы высмеивали только необходимые зависимости тестируемого класса.
[TestClass]
public class MainClassTests {
[TestMethod]
public void Should_AddDetails_To_Database() {
// Arrange
var mockDb = new Mock<IDatabase>();
var data = new Data();
var mainClass = new MainClass(Mock.Of<ILogger>(), mockDb.Object);
// Act
mainClass.AddDetails(data);
// Assert
mockDb.Verify(_ => _.Add(data), Times.Once);
}
}