Net Core ILogger Value cannot be null

Viewed 14612

I am receiving Logger Value cannot be null. I am trying to resolve this, maybe something with dependency injection. The error is received at the Unit test and everywhere else in the program. Am I conducting dependency injection correct?

Expected: <System.ArgumentException>
But was:  <System.ArgumentNullException: Value cannot be null.
  Parameter name: logger
  at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger logger,
                     LogLevel logLevel, EventId eventId, Exception exception,
                     String message, Object[] args)   

My code is as follows:

using System;
using ElectronicsStore.Models;
using Microsoft.Extensions.Logging;

namespace ElectronicsStore.Service
{
    public class ParseVendorSupply
    {
        private readonly ILogger _logger;

        public ParseVendorSupply(ILogger logger)
        {
            _logger = logger;
        }

        public VendorSupply FromCsv(string csvLine)
        {
            VendorSupply vendorsupply = new VendorSupply();

            try
            {
                string[] values = csvLine.Split(',');
                if (values.Length > 3)
                {
                    throw new System.ArgumentException("Too much data");
                }

                vendorsupply.VendorId = Convert.ToInt16(values[0]);
                vendorsupply.ProductId = Convert.ToInt16(values[1]);
                vendorsupply.Quantity = Convert.ToInt16(values[2]);
            }
            catch (Exception)
            {
                _logger.LogInformation("An exception was thrown attempting");
            }
            return vendorsupply;
        }       
    }
}

public Startup(IConfiguration configuration, ILogger<Startup> logger)
{
    Configuration = configuration;
    _logger = logger;
 }

public void ConfigureServices(IServiceCollection services)
{
     services.AddSingleton(new LoggerFactory().AddConsole().AddDebug());
     services.AddLogging();

NUnit Test:

public class ParseVendorSupplyNunit
{

    ILogger logger;

    //conducting this gives me an error, since cannot create instance of abstract class, not sure what alternative is
    //ILogger logger = new ILogger();

    [Test]
    public void FromCsv_ParseCorrectly_Extradata()
    {
        string csvLineTest = "5,8,3,9,5";
        ParseVendorSupply parseVendorSupplytest = new ParseVendorSupply(logger);
        //VendorSupply vendorsupply = parseVendorSupplytest.FromCsv(csvLineTest);
        Assert.That(() => parseVendorSupplytest.FromCsv(csvLineTest), Throws.ArgumentException);
    }
2 Answers

You have to initialize the logger variable with either an implementation of ILogger like ConsoleLogger or something similar. At the moment you aren't assigning any value to your test logger variable.

I would recommend passing in a mock of the logger because you're unit testing and probably don't want to test the logger itself. So use FakeItEasy or some other Mocking-Libary and create a faked instance over A.Fake<ILogger>()

You should follow the null object pattern here. Allow the ILogger parameter to be null, but default the field to NullLogger.Instance if the parameter is null. That means that you can safely use the dependency in any scenario but it doesn't force anyone to pass an instance in. Read more about this here.

Related