Reputation: 4645
Consider a method with a try catch
like this:
try
{
person = this.personRepo.GetPerson(name);
}
catch (PersonException)
{
LogHelper.LogDebug("PersonService", "No Person found!");
}
In the unit test, the personRepo
is faked with FakeItEasy:
A.CallTo(() => this.personRepository.GetPerson(personName)).Throws(new PersonException("Person not found"));
Question:
How can I check if the static logger was called?
Upvotes: 2
Views: 5356
Reputation: 247088
The assumption here is that the personRepo
is injected into the subject under test. Thus I also assume you are using DI.
The currently displayed code is tightly coupled to static implementation concerns which make it difficult to test the subject in isolation.
To make the subject more flexible and easier to maintain and test in isolation, the subject would need to be refactored to depend on an abstraction and not on a concretion.
Encapsulate the static LogHelper
behind an abstraction.
public interface ILogger {
void LogDebug(string category, string msg);
//...other members
}
which would wrap the desired behavior/functionality
public class LogHelperWrapper : ILogger {
public void LogDebug(string source, string msg) {
LogHelper.LogDebug(source, msg);
}
//...other members
}
The subject would make use of the abstraction, which would have refactored to follow explicit dependency principle via constructor injection.
private ILogger log; //set via constructor injection
try {
person = this.personRepo.GetPerson(name);
} catch (PersonException) {
this.log.LogDebug("PersonService", "No Person found!");
}
This will allow the subject under test to receive a replacement when tested in isolation.
//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.
Upvotes: 8