如何对依赖于基类的方法进行单元测试? [英] How do I unit test the method which has dependency on base classes?
问题描述
我有一个以下类,它具有基类,并且我正在尝试编写单元测试.
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屋!