I have an interface which is used in an MVC controller which gets some data. To keep it simple the interface so far looks something like this:
public interface IDataProvider
{
DataModel GetData();
}
I have appropriate unit tests for this interface where it is called in the action. However, in the real implementation this will call a web service which of course could throw an exception, therefore if it does I want to write a test to ensure that I log a message if an error occurs.
To do this I have a logger interface which is actually an interface to NLog called ILogger. I could do this:
public interface IDataProvider
{
DataModel GetData(ILogger logger);
}
This would allow me to run unit tests for the logger making it nice and simple. However, I don't think this is the right way of doing this because the logger is really unrelated to this method. Also, if I start adding other methods to this interface which I need logging for then I will have to include the logger in the parameter of all of those methods as well.
The best way I can think of right now is to include the logger in the constructor of my implementation which might look like this:
public class DataProvider : IDataProvider
{
private readonly ILogger _logger;
public DataProvider(ILogger logger)
{
_logger = logger;
}
public DataModel GetData()
{
// CODE GOES HERE
}
}
However this means that I cannot test the logger in my unit tests. What is the best way to achieve this so that I can keep the logger separate from the method and make it testable?
I'll appreciate any help, thanks.
EDIT:
I realise I missed out unit testing code here is what I mean:
At the moment I am ensuring that GetData is called in my action this way:
var controller = new DataController(_dataProvider.Object);
controller.Index();
_dataProvider.Verify(dataProvider => dataProvider.GetData());
What I'd like to do is the same but for the logger but only if an exception is thrown like this:
_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>());
Obviously logger would be given to data provider in the setup. I hope that makes a bit more sense.
You can try using the factory pattern.
What happens here is in your production code, you are getting the logger from a Factory. In this factory, it returns either your real logger, or a fake logger which is setup in your unit tests. To your production code, it makes no difference what-so-ever.
In your Unit Tests, you are using a fake logger created using Moq. This fake allows you to test that an interface method was called, in this case ILogger.Log(). This is done by using the .Verify method.
Try something like this:
ILogger.cs
public interface ILogger
{
void Log(string message);
}
LoggerFactory.cs
public static class LoggerFactory
{
public static ILogger Logger
{
get
{
return LoggerFactory._logger == null ? new Logger() : LoggerFactory._logger;
}
set
{
LoggerFactory._logger = value;
}
}
private static ILogger _logger = null;
}
DataProvider.cs
public void GetData()
{
var logger = LoggerFactory.Logger;
logger.Log("..."); // etc...
}
UnitTest.cs
private void Mock<ILogger> _mockLogger = null;
public void Load()
{
this._mockLogger = new Mock<ILogger>();
LoggerFactory.Logger = _mockLogger.Object;
}
public void UnitTest()
{
// test as required
this._mockLogger.Verify(m => m.Log(It.IsAny<string>()));
}
Use a mocking framework (e.g. Moq or RhinoMocks) to verify that the logger was called. Then the final code block you post, where the logger is passed in via the constructor, will work.
Passing logger (or any other dependencies) in constructor is very standard practice and allows you to use dependency injection framework if needed.
I'm not sure why you see passing logger in constructor as limiting for unit test: you have 3 components that you can test separately
controller (depends on data provide, mock this dependency to test),
data provider (depends on logging and some other classes that let you call web service - mock all dependencies so you know when logging called and no need to call Web service)
logging - not sure what it depends on, but should be testable separately.
Notes:
use mocking framework (i.e. moq ) for your tests - you'll be able to provide any implementations of interfaces (including exceptions) very easily.
see if dependency injection framework (i.e. Unity ) would work for you. MVC4 is very well suited for it.
If you need to test that the logger is being called, I suggest using a test double called a "spy". This would not do any logging, but keep track of which methods (if any) were called. Then you can verify that the logger is called in specific instances.
You could do this by using a mocking framework to create the double (or mock) for you. Or you could create the ILogger implementation yourself. For example:
class LoggerSpy : ILogger
{
public string LogWasCalled;
public void Log(string message)
{
LogWasCalled = true;;
}
}
The following seems to have an example of mocking an ILogger using Moq: How to Mock ILogger / ILoggerService using Moq
Related
When using LibLog, is it possible to assert calls to the logger? Given the wiki lists the following example for usage:
public class MyClass
{
private static readonly ILog Logger = LogProvider.For<MyClass>();
}
Here the logger is an implementation detail hidden from the consumer, which is most of the benefit of using this library. Such that the library consumer does not have to worry about how loggers are instantiated. Looking at this blog post:
http://dhickey.ie/2015/06/capturing-log-output-in-tests-with-xunit2/
It seems that a lot of boiler plate is added to capture the log output, I'm not entirely sure about the approach, given that it also uses a redirected Serilog output in the unit test, something that seems odd given the library should only rely on the logging abstraction?
The only options I can currently think of are:
Inject the logger - This probably would be odd for the consumer of the library, and each library then would carry it's own ILogger definition that needs to be injected, defeating the advantages of the abstraction.
Wire up to a real logging framework - Set the current LogProvider for LibLog to use Log4Net or similar, and then somehow try and inject a mock / stub Logger into Log4Net, and assert calls via proxy.
Any relatively simple way to assert calls to the logger would be appreciated, but I suspect parallel test execution would cause problems even if it was possible to assert calls on the above logger?
In the logging config for almost all loggers you can configure then to throw exception when log fail.
Sample from nlog
<nlog throwExceptions="true">
... your nlog config
</nlog>
But in the abstraction created by LibLog you lost this features
What I've done in my project:
I've created my LoggerFactory. It exposes same static methods as NLogger.
public class LoggerFactory
{
private static ILoggerFactoryStrategy _loggerFactoryStrategy = new DummyLoggerFactoryStrategy();
public static void Initialize(ILoggerFactoryStrategy loggerFactoryStrategy)
{
_loggerFactoryStrategy = loggerFactoryStrategy;
}
public ILogger GetLogger<T>()
{
return _loggerFactoryStrategy.GetLogger<T>();
}
....
}
Dummy strategy can write just to debug output or do nothing. Another strategy could look smth like:
public class LoggerFactoryStrategy : ILoggerFactoryStrategy
{
public ILogger GetLogger<T>()
{
//create LibLog instance instead with LogProvider.For<T>()
var nlogger = LogManager.GetLogger(typeof(T).Name); //create instance of NLogger
return new NLogLogger(nlogger);
}
}
And NlogLogger wrapper could be smth like
internal class NLogLogger : ILogger
{
private readonly Logger _logger;
public NLogLogger(Logger logger)
{
_logger = logger;
}
public void Debug(string message)
{
_logger.Debug(message);
}
public void Warn(string message, params object[] args)
{
_logger.Warn(message, args);
}
public void Info(Exception exception)
{
_logger.Info(exception);
}
......
}
When application starts I initialize it with proper strategy what uses NLogger under the hood.
If I want to test calls to logger I can use mocked strategy.
This approach lets you to remove references to logger library across your solution, except your root projects and lets you switch from one to another if you need in the future.
Also, this allowed us to use NLogger in PCL projects.
(I originally asked this question in this comment, but Mark Seemann asked me to create a new question instead.)
I'm starting a new app (.NET Core, if that matters), and right now I'm trying to decide how exactly to do logging.
The general consensus seems to be that logging is a cross-cutting concern, so the logger shouldn't be injected directly into the class that is supposed to log.
Often, there's an example like the following class how not to do it:
public class BadExample : IExample
{
private readonly ILogger logger;
public BadExample(ILogger logger)
{
this.logger = logger;
}
public void DoStuff()
{
try
{
// do the important stuff here
}
catch (Exception e)
{
this.logger.Error(e.ToString());
}
}
}
Instead, the class with the business logic shouldn't know about the logger (SRP) and there should be a separate class which does the logging:
public class BetterExample : IExample
{
public void DoStuff()
{
// do the important stuff here
}
}
public class LoggingBetterExample : IExample
{
private readonly IExample betterExample;
private readonly ILogger logger;
public LoggingBetterExample(IExample betterExample, ILogger logger)
{
this.betterExample = betterExample;
this.logger = logger;
}
public void DoStuff()
{
try
{
this.betterExample.DoStuff();
}
catch (Exception e)
{
this.logger.Error(e.ToString());
}
}
}
Whenever an IExample is needed, the DI container returns an instance of LoggingBetterExample, which uses BetterExample (which contains the actual business logic) under the hood.
Some sources for this approach:
Blog posts by Mark Seemann:
Instrumentation with Decorators and Interceptors
Dependency Injection is Loose Coupling
Blog post and SO answer by Steven:
Meanwhile... on the command side of my architecture
Windsor - pulling Transient objects from the container
My question:
Obviously, the LoggingBetterExample approach only works as long as the logging can be done outside the actual class.
(like in the example above: catch any exceptions thrown by BetterExample from outside)
My problem is that I'd like to log other things inside the actual class.
Mark Seemann suspected here that if someone needs to do this, maybe the method in question is doing too much.
As I said before, I'm in the planning phase for a new application, so I don't have much code to show, but the use case I'm thinking right now is something like this:
My app will have a config file with some optional values.
The user may decide to omit the optional values, but it's an important decision to do this.
So I'd like to log a warning when some of the optional values are missing, just in case it happened by error.
(omitting the values is perfectly fine though, so I can't just throw an exception and stop)
This means that I will have a class which reads config values and needs to do something like this (pseudocode):
var config = ReadConfigValues("path/to/config.file");
if (config.OptionalValue == null)
{
logger.Warn("Optional value not set!");
}
No matter if ReadConfigValues is in this class or a different one, I don't think this class would violate the SRP.
When I'm not able to log outside the actual class by using a decorator, is there a better solution than to inject the logger?
I know I could read the config file in the inner class, but check the values (and log the warning) in the decorator. But IMO checking the value is business logic and not infrastructure, so to me it belongs in the same class where the config file is read.
checking the value is business logic and not intfastructure, so to me it belongs in the same class where the config file is read.
Obviously, I don't know your domain well enough to dispute the truth of that assertion, but that logging is part of the domain model sounds strange to me. Anyway, for the sake of argument, let's assume that this is the case.
What ought not to be the case, though, is that reading a configuration file is domain logic. While reading and manipulating the data from a file could easily be domain logic, reading a file is I/O.
The most common approach to Inversion of Control in application architecture is to employ the Ports & Adapters architecture. The entire point of such an architecture is to decouple the domain model from I/O, and other sources of non-determinism. The poster example is to show how to decouple the domain model from its database access, but file access falls squarely in that category as well.
What this ought to imply in this particular case is that you're going to need some IConfigurationReader interface anyway. This means that you can apply a Decorator:
public class ValidatingConfigurationReader : IConfigurationReader
{
private readonly IConfigurationReader reader;
private readonly ILogger logger;
public ValidatingConfigurationReader(IConfigurationReader reader, ILogger logger)
{
this.reader = reader;
this.logger = logger;
}
public MyConfiguration ReadConfigValues(string filePath)
{
var config = this.reader.ReadConfigValues(filePath);
if (config.OptionalValue == null)
{
this.logger.Warn("Optional value not set!");
}
return config;
}
}
This ValidatingConfigurationReader class can be implemented in the domain model, even if the underlying, file-reading IConfigurationReader implementation belongs in some I/O layer.
Don't take SRP so seriously, otherwise you'll end up with functional programming. If you afraid of getting your class cluttered by putting log statements inside it, then you have two options. The first one you already mentioned which is using a Decorator class but you can't access/log the private stuff. The second option is using partial classes and putting the logging statements in a separate class.
I've got a controller with a lot of constructor injection:
public MoviesController(ISession session, IClientContext clientContext, PManager pManager, ISegmentationService segmentationService, IGeoLocator geoLocator, IBus bus)
{
_session = session;
_clientContext = clientContext;
_pManager = pManager;
_segmentationService = segmentationService;
_geoLocator = geoLocator;
_bus = bus;
}
From my understanding (just read about Mocking), I've got a lot of Mock object properties to manually set if I wish to make a comprehensive test suite based on this controller.
For one method I'm only using one service (I'd even like to automate that with little effort if possible):
public object Show(Guid id)
{
var movie = _session.Get<movie>(id);
return movie;
}
But in another there are many services being used - is there any way to set those Moq objects up quickly? I could really use some examples as I'm new to testing. It's an asp.net mvc project with webapi 1 bundled in (testing the webapi controller here)
As has been said in the comments, if you have common setup code, you can put it in a Setup method that is called automatically from your testing framework before each test. It's decorated with a Setup attribute if you're using Nunit TestInitialize if you're using MStest. If you're using XUnit then it's a bit different.
So, your class might look like this:
public class SomeTests {
Mock<ISession> _sessionMock;
Mock<IClientContext> _clientContextMock;
[Setup]
public void Setup() {
_sessionMock = new Mock<ISession>();
_clientContextMock = new Mock <IClientContext();
}
MovieController CreateSut() {
return new MovieController(_sessionMock.Object, _clientContextMock.Object, ...);
}
[Test]
public void TestSomething() {
_sessionMock.Setup(x=>...);
//...
var sut = CreateSut();
//...
}
}
If you're trying to get away from completely creating the mocks manually, then you might want to look at something like AutoFixture with AutoMoq. Which will automatically supply mock instances when creating objects that accept interfaces. AutoFixture can be quite useful, but there is a learning curve to using it effectively so you might want to look at a tutorial / quickstart.
You could also configure an IOC container to supply mock instances for your test project, although I've never gone down that route myself.
For your example, you only need to mock the session, and can leave all the other dependencies null, since their behaviour should be irrelevant to the behaviour you are testing:
Mock<ISession> mockSession = new Mock<ISesssion>();
MoviesController controller = new MoviesController(mockSession.Object, null,null,null,null,null);
There is no need for you to set up any mocks other than the ones you need for this particular test
We are looking at adding unit tests to our C# code base. I am finding it easy to add unit tests to simple classes, but classes that interact with other dependencies are more difficult. I have been looking at mocking frameworks, but was wondering about the best approach to write classes in the first place to break external dependencies, like file system, database and messaging system dependencies.
To give an example, a routine listens on a socket for a message in a certain format - say MessageA. This is decoded, some calculations are done, this is re-encoded into a different binary format and the resulting message then sent, MessageB.
My current testing approach is as follows. I extract an interface for all socket interactions, and create a mock interface. I set the interface in a singleton. Then run the class against hard coded inputs. The class under test will use the interface in the singleton to send/receive.
I do a similar thing to test database interactions.
This does not seem like the most flexible approach, how would you go about improving this to make it easier to test? If a mocking framework is the answer, how would I design the classes?
Example code :
[SetUp]
public void init()
{
// set message interface in singleton as mock interface
CommAdapter.Instance.MessageAdapter = new MockMessage();
// build reference message from hard coded test variables
initialiseMessageA();
// set input from mock message socket
((MockMessage) CommAdapter.Instance.MessageAdapter).MessageIn = m_messageA;
}
[Test]
public void test_listenMessage_validOutput()
{
// initialise test class
MessageSocket tS = new MessageSocket();
// read from socket
tS.listenMessage();
// extract mock interface from singleton
MockMessage mm = ((MockMessage) CommAdapter.Instance.MessageAdapter);
// assert sent message is in correct / correstpoinding format
Assert.AreEqual(1000001, mm.SentMessageB.TestField);
}
Instead of using Singletons to set your component implementations, use a Dependency Injection, and a DI library like Ninject. This is exactly the type of scenario they were designed for.
Not pushing you to Ninject specifically, but they have a good tutorial :) The concepts will transfer to other frameworks (like Unity).
https://github.com/ninject/ninject/wiki
With DI alone, the code will look something like this:
class Samurai {
private IWeapon _weapon;
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
public void Attack(string target) {
_weapon.Hit(target);
}
}
class Shuriken : IWeapon {
public void Hit(string target) {
Console.WriteLine("Pierced {0}'s armor", target);
}
}
class Program {
public static void Main() {
Samurai warrior1 = new Samurai(new Shuriken());
Samurai warrior2 = new Samurai(new Sword());
warrior1.Attack("the evildoers");
warrior2.Attack("the evildoers");
}
}
This looks clean now, but wait until your dependencies have dependencies, or further :) You can use a DI library to solve that, though.
With a library to handle the wiring up for you, it will look something like:
class Program {
public static void Main() {
using(IKernel kernel = new StandardKernel(new WeaponsModule()))
{
var samurai = kernel.Get<Samurai>();
warrior1.Attack("the evildoers");
}
}
}
// Todo: Duplicate class definitions from above...
public class WarriorModule : NinjectModule {
public override void Load() {
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
With either of these approaches, plus a mock object framework like Moq, your unit tests look something like this:
[Test]
public void HitShouldBeCalledByAttack()
{
// Arrange all our data for testing
const string target = "the evildoers";
var mock = new Mock<IWeapon>();
mock.Setup(w => w.Hit(target))
.AtMostOnce();
IWeapon mockWeapon = mock.Object;
var warrior1 = new Samurai(mockWeapon);
// Act on our code under test
warrior1.Attack(target);
// Assert Hit was called
mock.Verify(w => w.Hit(target));
}
You'll notice you can just pass mock instances straight into the code under test, and you don't have to mess around with setting singletons. This will help you avoid problems like needing to set up the state multiple times, or in between calls. It means no hidden dependencies.
You'll also notice I didn't use the DI container in the tests. If your code is well factored, it will only be testing a single class (and as often as possible, only a single method), and you will only need to mock out the direct dependencies of that class.
In addition to a DI container (I'm using MS Unity 2.0 currently but there are many to choose from) you will need a good mocking framework, my preference is MOQ. A common pattern/process for breaking concrete dependencies is:
define the dependency via an interface; you may luck out and already have an interface, like IDbConnection or you may need to use Proxy to wrap a concrete type and define your own interface.
resolve the concrete implementation via your DI container
inject your mock implementations into your DI container at test setup time (inject real impls. at system startup)
I am confused right now, and maybe does not understand the real problem.
I have an object which require logger instance to log error data.
for example
public class CommonFileSaver : IFileSaver
{
private static ILog _log = LogManager.GetLogger();
.....
}
I wish to test the logging process. And my current decission is to use the mock of the ILog interface.
At this point I have decided to use Unity to resolve dependencies.
So the line
ILog _log = LogManager.GetLogger();
will look something like
ILog _log = Resolver.Instance.Resolve<ILoger>();
The question is how to setup the Unity container to return me new instance of the ILog object using LogManager factory.
Thank you.
P.S. ILog is the log4net interface, and the whole logging thing is implemented using log4net right now.
Maybe it is not correct in design, but using factory is possible in Unity...
_container = new UnityContainer();
_container.RegisterType<ILog>(new InjectionFactory(c => LogManager.GetLogger()));
The problem here is that you're not following the Hollywood principle. Static factory methods and singletons don't fit well with dependency injection. You should change your code, to inject your ILog factory:
public class CommonFileSaver : IFileSaver
{
public CommonFileSaver(ILogFactory logFactory)
{
_log = logFactory.GetLogger();
}
private readonly ILog _log;
.....
}
You could write a wrapper for log4net (something which imho is a good idea anyway). The wrapper would take care of creating the instances by using the log4net factory method and it would also make sure that the "Configure" method is called.
If you write a wrapper you might want to consider this information.
If the goal of what you are trying to achieve is to test the logging process with a mock ILog when I would suggest that you also mock the LogManager and set up an expectation on the GetLogger so that it will return the mock ILog.