I have a class
public class NLogRuleComposer : INLogComponentComposer
{
private LoggingConfiguration _nLogLoggingConfiguration;
//TODO: think we need to constructor-inject the logging config
public void ComposeComponent(LoggerModel loggerModel
, LoggingConfiguration nLogLoggingConfiguration
, string loggerFullName)
{
_nLogLoggingConfiguration = nLogLoggingConfiguration;
var ruleName = loggerFullName;
var minimumLevel = LogLevel.FromString(loggerModel.level.min_level);
var maximumLevel = LogLevel.FromString(loggerModel.level.max_level);
var allTargetsWithLayout = nLogLoggingConfiguration.AllTargets.OfType<TargetWithLayout>().ToList();
var targetWithoutStackTrace = allTargetsWithLayout
.FirstOrDefault(x => x.Name.Contains("WithoutStacktrace"));
var targetWithStackTrace = allTargetsWithLayout.FirstOrDefault(x => x.Name.Contains("WithStacktrace"));
CreateDefaultLevelFilter(ruleName, maximumLevel.Name, minimumLevel, targetWithoutStackTrace);
}
public void CreateDefaultLevelFilter(string ruleName, string maximumLevelName
, LogLevel minimumLevel, TargetWithLayout targetWithoutStackTrace)
{
var filter = new ConditionBasedFilter();
filter.Action = FilterResult.Log;
filter.Condition = "(level <= LogLevel." + maximumLevelName + ")";
var loggerRule = new LoggingRule(ruleName, targetWithoutStackTrace);
loggerRule.Filters.Add(filter);
_nLogLoggingConfiguration.LoggingRules.Add(loggerRule);
}
Now I want to test CreateDefaultLevelFilter
method, but it is void. I don't know how to test it and test what. Using Mock maybe?
Unfinished code:
public class NLogRuleComposerUnitTests
{
[Theory]
[InlineData("MyLoggerName")]
public void NLogRuleComposer_Should_Create_A_LoggingRule(
string expectedLogger)
{
var nLogRuleComposerMock = new Mock<INLogComponentComposer>();
var nLogTargetMock = new Mock<TargetWithLayout>();
nLogRuleComposerMock.Setup(x => x.ComposeComponent(It.IsAny<LoggerModel>()
, It.IsAny<LoggingConfiguration>()
, It.IsAny<string>()))
.Verifiable();
}
}
You'll be in troubles to test that piece of code without some dependency injection. Creating instances like this
it make impossible to unit test since, as side effect, you're also testing class
ConditionBasedFilter
. Your unit test, ideally, should not test anything except method result or behavior. External dependencies should be mocked.What I would do:
filter
If you don't have the habit of inject dependencies, you should start making this habit :) Without that, it's impossible to do unit test properly.
This is an example of how you could test
ConditionBasedFilter
propertiesThen, you use the factory like this inside your
CreateDefaultLevelFilter
methodAt the end of your test, you assert that filter was set with correct values for
Action
andCondition
. Similar applies forloggerRule