如果调用静态记录器,如何进行单元测试

xer*_*him 1 .net c# logging unit-testing fakeiteasy

考虑一个try catch像这样的方法:

try
{
    person = this.personRepo.GetPerson(name);
}
catch (PersonException)
{
    LogHelper.LogDebug("PersonService", "No Person found!");
}
Run Code Online (Sandbox Code Playgroud)

在单元测试中,personRepo伪造的是FakeItEasy:

A.CallTo(() => this.personRepository.GetPerson(personName)).Throws(new PersonException("Person not found"));
Run Code Online (Sandbox Code Playgroud)

题:

如何检查静态记录器是否被调用?

Nko*_*osi 5

这里的假设是将其personRepo注入受试者体内.因此我也假设你正在使用DI.

当前显示的代码与静态实现问题紧密耦合,这使得难以单独测试主题.

为了使主题更灵活,更容易维护和单独测试,需要对主题进行重构以依赖抽象而不是结果.

将静态封装在LogHelper抽象之后.

public interface ILogger {
    void LogDebug(string category, string msg);
    //...other members
}
Run Code Online (Sandbox Code Playgroud)

这将包装所需的行为/功能

public class LogHelperWrapper : ILogger {
    public void LogDebug(string source, string msg) {
        LogHelper.LogDebug(source, msg);
    }

    //...other members
}
Run Code Online (Sandbox Code Playgroud)

主题将使用抽象,抽象将通过构造函数注入重构为遵循显式依赖原则.

private ILogger log; //set via constructor injection
try {
    person = this.personRepo.GetPerson(name);
} catch (PersonException) {
    this.log.LogDebug("PersonService", "No Person found!");
}
Run Code Online (Sandbox Code Playgroud)

这将允许被测对象在单独测试时接收替换.

//Arrange
var logger = A.Fake<ILogger>();
//...other arrangements

//Act
//...exercise test

//Assertion
A.CallTo(() => logger.LogDebug("PersonService", "No Person found!"))
.MustHaveHappened(Repeated.Exactly.Once);
//...other assertions.
Run Code Online (Sandbox Code Playgroud)