我有一个用于获取一些数据的 MVC 控制器的接口。为了简单起见,到目前为止的界面看起来像这样:
public interface IDataProvider
{
DataModel GetData();
}
我对此接口进行了适当的单元测试,该接口在操作中被调用。但是,在实际实现中,这将调用一个 Web 服务,当然这可能会引发异常,因此,如果它确实发生了,我想编写一个测试以确保在发生错误时记录一条消息。
为此,我有一个记录器接口,它实际上是一个名为 ILogger 的 NLog 接口。我可以这样做:
public interface IDataProvider
{
DataModel GetData(ILogger logger);
}
这将允许我为记录器运行单元测试,使其变得简单易用。但是,我认为这不是正确的方法,因为记录器实际上与此方法无关。此外,如果我开始向此接口添加其他需要记录的方法,那么我也必须将记录器包含在所有这些方法的参数中。
我现在能想到的最好方法是将记录器包含在我的实现的构造函数中,它可能看起来像这样:
public class DataProvider : IDataProvider
{
private readonly ILogger _logger;
public DataProvider(ILogger logger)
{
_logger = logger;
}
public DataModel GetData()
{
// CODE GOES HERE
}
}
但是,这意味着我无法在单元测试中测试记录器。实现此目的的最佳方法是什么,以便我可以将记录器与方法分开并使其可测试?
我会很感激任何帮助,谢谢。
编辑:
我意识到我错过了单元测试代码,这就是我的意思:
目前,我确保在我的操作中以这种方式调用 GetData:
var controller = new DataController(_dataProvider.Object);
controller.Index();
_dataProvider.Verify(dataProvider => dataProvider.GetData());
我想做的是相同的,但对于记录器,但前提是抛出这样的异常:
_dataProvider.Setup(dataProvider => dataProvider.GetData()).Throws<WebException>();
var controller = new DataController(_dataProvider.Object);
controller.Index();
_logger.Verify(logger => logger.ErrorException(It.IsAny<string>(), It.IsAny<Exception>());
显然记录器将在设置中提供给数据提供者。我希望这更有意义。