如果发生对静态记录器的调用,如何进行单元测试
How to unit test if call to static logger happened
考虑一个带有 try catch
的方法,如下所示:
try
{
person = this.personRepo.GetPerson(name);
}
catch (PersonException)
{
LogHelper.LogDebug("PersonService", "No Person found!");
}
在单元测试中,personRepo
是用 FakeItEasy 伪造的:
A.CallTo(() => this.personRepository.GetPerson(personName)).Throws(new PersonException("Person not found"));
问题:
如何检查是否调用了静态记录器?
这里的假设是personRepo
被注入被测对象。因此,我还假设您正在使用 DI。
当前显示的代码与静态实现问题紧密耦合,这使得很难单独测试主题。
为了使主题更灵活、更易于维护和单独测试,需要重构主题以依赖于抽象而不是具体化。
封装抽象背后的静态LogHelper
。
public interface ILogger {
void LogDebug(string category, string msg);
//...other members
}
这将包装所需的 behavior/functionality
public class LogHelperWrapper : ILogger {
public void LogDebug(string source, string msg) {
LogHelper.LogDebug(source, msg);
}
//...other members
}
主题将使用抽象,这将通过构造函数注入重构以遵循显式依赖原则。
private ILogger log; //set via constructor injection
try {
person = this.personRepo.GetPerson(name);
} catch (PersonException) {
this.log.LogDebug("PersonService", "No Person found!");
}
这将允许接受测试的对象在隔离测试时接受替换。
//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.
考虑一个带有 try catch
的方法,如下所示:
try
{
person = this.personRepo.GetPerson(name);
}
catch (PersonException)
{
LogHelper.LogDebug("PersonService", "No Person found!");
}
在单元测试中,personRepo
是用 FakeItEasy 伪造的:
A.CallTo(() => this.personRepository.GetPerson(personName)).Throws(new PersonException("Person not found"));
问题:
如何检查是否调用了静态记录器?
这里的假设是personRepo
被注入被测对象。因此,我还假设您正在使用 DI。
当前显示的代码与静态实现问题紧密耦合,这使得很难单独测试主题。
为了使主题更灵活、更易于维护和单独测试,需要重构主题以依赖于抽象而不是具体化。
封装抽象背后的静态LogHelper
。
public interface ILogger {
void LogDebug(string category, string msg);
//...other members
}
这将包装所需的 behavior/functionality
public class LogHelperWrapper : ILogger {
public void LogDebug(string source, string msg) {
LogHelper.LogDebug(source, msg);
}
//...other members
}
主题将使用抽象,这将通过构造函数注入重构以遵循显式依赖原则。
private ILogger log; //set via constructor injection
try {
person = this.personRepo.GetPerson(name);
} catch (PersonException) {
this.log.LogDebug("PersonService", "No Person found!");
}
这将允许接受测试的对象在隔离测试时接受替换。
//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.