2

I'm creating a solution that contains two projects: the web project ant it's test project. I'm using Log4net for logging purposes, CastleWindsor for dependency injection and moq for the tests.

The problem I have is the configuration of the test. I want to test the HomeController that is Logging to a file, but when I run the test I don't want to Log, I think is absurd.

Is there a way to skip Logging in the test project?

The HomeController class:

public class HomeController : Controller
{
    // this is Castle.Core.Logging.ILogger, not log4net.Core.ILogger
    public ILogger Logger { get; set; }

    private IRowan _rowan;

    public HomeController(IRowan rowan)
    {
        _rowan = rowan;

    }

    public ActionResult Index()
    {
        //In the [tests] Logger fails
        Logger.Debug("GET Request traced");
        Logger.Error("Example of Error");


        String test = _rowan.DoSomething();
        ViewBag.Title = test;
        return View();
    }
}

}

It's test:

[TestClass]
public class HomeControllerTest
{
    private static WindsorContainer _container;

    [ClassInitialize()]
    public static void InstallWindsor()
    {
        _container = new WindsorContainer();
        // configure other classes
    }

    [ClassCleanup()]
    public static void DisposeContainer()
    {
        _container.Dispose();
    }

    [TestMethod]
    public void Index()
    {
        // Disponer
        var mock = new Mock<IRowan>();

        mock.Setup(m => m.DoSomething()).Returns("Home Page");

        HomeController controller = new HomeController(mock.Object);

        // Actuar
        ViewResult result = controller.Index() as ViewResult;

        // Declarar
        Assert.IsNotNull(result);
        Assert.AreEqual("Home Page", result.ViewBag.Title);
    }
}

If the answer is no, which is the best way to implement log4net for testing?

PD: When I run the code, It works fine. When I run the test, Logger throws an exception because is null.

PD: I'm starting using the Microsoft Technology.

Albert Lazaro de Lara
  • 2,540
  • 6
  • 26
  • 41
  • Just to clear it up - you're dependency injecting the logger too? That's normally the one thing you don't bother with - [see this for example](https://stackoverflow.com/questions/12591955/should-logging-infrastructure-be-injected-when-using-ioc-di-if-logging-facade-is). That way you won't be logging during your tests simply because the logger won't be configured to do so. – James Thorpe Jul 10 '17 at 08:03
  • The logger is injected using the Nugget package **Castle.Windsor-log4net**, and I follow [this tutorial](https://github.com/castleproject/Windsor/blob/master/docs/mvc-tutorial-part-5-adding-logging-support.md) to configure it. – Albert Lazaro de Lara Jul 10 '17 at 08:06

2 Answers2

2

You could mock your Logger and set it on your controller like so:

Mock<ILogger> mockLogger = new Mock<ILogger>();
controller.Logger = mockLogger.Object;

Note that you shouldn't really need to use CastleWindsor in your tests. That's useful for controlling the lifecycle of objects in your application but in your tests you should be injecting things by hand. You are actually doing this in the example above. From the code you've posted you can remove the ClassInitialize and ClassCleanup functions and it will run the same.

PeteG
  • 541
  • 5
  • 15
1

You can use an other config for your test project. Read more: https://logging.apache.org/log4net/release/manual/configuration.html

Jonas Benz
  • 503
  • 3
  • 12