如何对依赖于基类的方法进行单元测试? [英] How do I unit test the method which has dependency on base classes?

查看:135
本文介绍了如何对依赖于基类的方法进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个以下类,它具有基类,并且我正在尝试编写单元测试.

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();

解决方案

您没有设置容器工厂的行为,因此,当您调用.GetInstance<IAuditRepository>()时,它将返回 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);

I have a below class, which having base class and I am trying to write unit test.

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 is part of base class. CurrentContext.ContainerFactory throws null exception. How do I create Mock for these classes?

Is interface is must for unit testing?

Updated with base class

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 class

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

Unit Test Class

       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();

解决方案

You did not setup the container factory's behavior so when you call .GetInstance<IAuditRepository>() it will return null, hence your error.

Provide the class under test with the necessary dependencies to allow the test to be exercised to completion.

//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);

这篇关于如何对依赖于基类的方法进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆