c# - 单元测试依赖注入(inject)

标签 c# unit-testing dependency-injection inversion-of-control

我正在使用 Autofac国际奥委会

这是我的容器启动器类,其职责是注册依赖项。

 public class ContainerInit
 {
      public static IContainer BuildContainer()
      {
            var conFac = new ContainerFactory();
            var builder = new ContainerBuilder();
            builder.Register(conFac).As<IContainerFactory>().SingleInstance();
            builder.Register(c=> new MainClass(conFac)).As<IMainClass>().SingleInstance();
            builder.Register(c=> new Database(conFac)).As<IDatabase>().SingleInstance();
             var logger = LoggUtil.CreateLogger();
            builder.Register(logger).As<ILogger>().SingleInstance();

            var container = builder.Build();
            ContainerFactory.SetContainer(container);
            return container;
      }
 }

这种方法的问题是,我需要通过 IContainerFactory我在我的应用程序中使用的每个类的构造函数如下
  public class MainClass: IMainClass
  {       
      private readonly ILogger _logger;
      private readonly IDatabase _db;
      public MainClass(IContainerFactory containerFactory)
      {
              _logger = containerFactory.GetInstance<ILogger>();  
              _db =  containerFactory.GetInstance<IDatabase>(); //example       
      }
      public AddDetails(Data data)
      {
        //do some business operations 
        _db.Add(data);
        _logger.Information("added");
      }
  }

所以很难对这些类进行单元测试。

怎样才能想出一个好的解决方案?

最佳答案

更好的方法是将类中所需的依赖项传递给构造函数:

public class MainClass : IMainClass
{       
    private readonly ILogger _logger;
    private readonly IDatabase _db;

    public MainClass(ILogger logger, IDatabase db)
    {
        _logger = logger;  
        _db = db;
    }

    public void AddDetails(Data data)
    {
        //do some business operations 
        _db.Add(data);
        _logger.Information("added");
    }
}

然后您可以使用模拟框架,例如 Moq模拟您的类依赖项并验证是否调用了依赖项:
[TestClass]
public class UnitTest1
{
    private Mock<ILogger> _mockLogger = new Mock<ILogger>();
    private Mock<IDatabase> _mockDb = new Mock<IDatabase>();

    [TestMethod]
    public void TestMethod1()
    {
        // arrange
        var mainClass = new MainClass(_mockLogger.Object, _mockDb.Object);
        var data = new Data();

        // act
        mainClass.AddDetails(data);

        // assert    
        _mockDb
            .Verify(v => v.Add(data), Times.Once);
    }
}

我不会验证您的日志消息,因为这可能会改变并使测试变得脆弱。仅验证对执行该方法的用途至关重要的功能。

关于c# - 单元测试依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56521382/

相关文章:

visual-studio - Visual Studio 测试项目 - 不在部署时复制文件夹

c# - 使用 Unity 的策略模式和依赖注入(inject)

dependency-injection - 使用 Autofac 注入(inject)特定类型

c# - CallContext.LogicalGetData() 与 ThreadLocal/ThreadStatic

c# - 如果文本不在某些指定的 HTML 标记内,则替换文本

python - Django测试客户端-发送POST数据返回400错误

ios - UISlider addTarget 和 sendActions 在 UT 中不起作用

c# - 温莎容器生活方式问题

c# - 有什么方法可以修改 Visual Studio 模板中的现有文件?

c# - 将 C# byte[] 传递给 C char 指针