【问题标题】:How do I unit test the method which has dependency on base classes?如何对依赖基类的方法进行单元测试?
【发布时间】:2018-07-23 07:09:24
【问题描述】:

我有一个下面的类,它有基类,我正在尝试编写单元测试。

public class CarService : ServiceBase, IProvisioningService
{
    private IAuditRepository _repository;
    public CarService(IHostingFactory hostingFactory) : base(name, hostingFactory)
    {         

    }

    public override void DoWork()
    {
        if (_repository == null)
          {
             //its calling the base method.
            _repository = CurrentContext.ContainerFactory.GetInstance<IAuditRepository>();                  
        try
        {
            _repository.Insert("something");
        }
        catch (Exception ex)
        {

        }
    }       
  }
}

CurrentContext.ContainerFactory 是基类的一部分。 CurrentContext.ContainerFactory 抛出空异常。如何为这些类创建 Mock?

接口是单元测试必须的吗?

用基类更新

public abstract class ServiceBase : IServiceBase
{
    public HostingContext CurrentContext { get; }
    public string ServiceName { get; }

    protected ServiceBase(string serviceName, IHostingFactory hostingFactory)
    {
        ServiceName = serviceName;

        _stopSignal = false;
        CurrentContext = hostingFactory.CreateContext(serviceName);
        Logger = CurrentContext.LoggerInstance;
    }

}

HostingContext 类

   public class HostingContext
   {
        public HostingContext(
        Func<string, ILogger> loggerFactory,
        string serviceName, 
        string connString): this(loggerFactory(contextName),serviceName, connString, new ContainerFactory())
    {}
 }

单元测试类

       MockRepository repository = new MockRepository(MockBehavior.Default);
       var containerFactoryMock = repository.Create<IContainerFactory>();
       var auditRepositoryMock = repository.Create<IAuditRepository>();
       var hostingFactoryMock = repository.Create<IHostingFactory>();
                   var hostingContextMock = new HostingContext("Sample", "ConnString",containerFactoryMock.Object);


        hostingFactoryMock.Setup(factory => factory.CurrentContext(It.IsAny<string>()))
            .Returns(hostingContextMock);
        CarService carService = new CarService(hostingFactoryMock.Object);

        carService.Work();

【问题讨论】:

  • 那么看起来你只需要为被测类提供必要的依赖项,就可以完成测试。提供具有所需行为的模拟 IHostingFactory 或提供存根实例(如果可能)。
  • 随测试更新。我觉得代码很乱。基本上我不想修复确切的代码,我想了解最佳实践和正确的模拟方式。这样我就可以从头开始编写干净的代码了。
  • 到目前为止一切顺利。您没有设置容器因素的行为,因此当您调用 .GetInstance&lt;IAuditRepository&gt;() 时,它将返回 null。因此你的错误。
  • 你能告诉我代码更改吗?
  • 检查提供的示例。

标签: c# unit-testing moq


【解决方案1】:

您没有设置容器工厂的行为,因此当您调用 .GetInstance&lt;IAuditRepository&gt;() 时,它将返回 null,因此您的错误。

为被测类提供必要的依赖项,以完成测试。

//Arrange
var repository = new MockRepository(MockBehavior.Default);
var containerFactoryMock = repository.Create<IContainerFactory>();
var auditRepositoryMock = repository.Create<IAuditRepository>();
var hostingFactoryMock = repository.Create<IHostingFactory>();
var loggerMock = repository.Create<ILogger>();

var hostingContextMock = new HostingContext(loggerMock, "Sample", "ConnString",containerFactoryMock.Object);

hostingFactoryMock
    .Setup(_ => _.CreateContext(It.IsAny<string>()))
    .Returns(hostingContextMock);

containerFactoryMock
    .Setup(_ => _.GetInstance<IAuditRepository>())
    .Returns(auditRepositoryMock);

CarService carService = new CarService(hostingFactoryMock.Object);

//Act
carService.Work();

//Assert
auditRepositoryMock.Verify(_ => _.Insert(It.IsAny<string>()), Times.Once);

【讨论】:

  • 我的 HostingContext 依赖于 Func loggerFactory。如何创建它的模拟?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多