Search code examples
c#.netninject

Ninject DI arguments passing to the unit test


It's my constructor with ILogger dependency

 public Book(string isbn, string author, string title, string publisher, int publishYear, ushort pageNumber, decimal price, ILogger logger)
    {
        Isbn = isbn;
        Author = author;
        Title = title;
        Publisher = publisher;
        PublishYear = publishYear;
        PageNumber = pageNumber;
        Price = price;
        _logger = logger;

        _logger.Log(LogLevel.Info, "Book constructor has been invoked");
    }

And my unit test with the attempt with solving it via Ninject framework

    [TestCase("9783161484100", "Some Name", "C# in a nutshell", "Orelly", 2014, (ushort)900, 60, ExpectedResult = "Some Name Orelly")]
    [Test]
    public string FormatBook_FortmattingBooksObject_IsCorrectString(string isbn, string author, string title, string publisher, int year, ushort pages, decimal price)
    {
        using (IKernel kernel = new StandardKernel())
        {
            var book = kernel.Get<Book>();    

            Console.WriteLine(book.FormatBook(book.Author, book.Publisher));

            return book.FormatBook(book.Author, book.Publisher);
        }

    }

And the question is, how I can inject the dependency and pass my arguments to the constructor?


Solution

  • There is no need to inject stuff in the unit test. Just use a mock object for the logger:

    [TestCase("9783161484100", "Some Name", "C# in a nutshell", "Orelly", 2014, (ushort)900, 60, ExpectedResult = "Some Name Orelly")]
    [Test]
    public string FormatBook_FortmattingBooksObject_IsCorrectString(string isbn, string author, string title, string publisher, int year, ushort pages, decimal price)
    {
            ILogger fakeLogger = ...; //Create some mock logger for consumption
            var book = new Book(isbn, author, title, publisher, year, pages, price, fakeLogger); 
            Console.WriteLine(book.FormatBook(book.Author, book.Publisher));
    
            return book.FormatBook(book.Author, book.Publisher);        
    }
    

    That is not to say that the logger cannot be supplied by a kernel too, if you so choose, but you would have to set it up first and then get it:

    [TestCase("9783161484100", "Some Name", "C# in a nutshell", "Orelly", 2014, (ushort)900, 60, ExpectedResult = "Some Name Orelly")]
    [Test]
    public string FormatBook_FortmattingBooksObject_IsCorrectString(string isbn, string author, string title, string publisher, int year, ushort pages, decimal price)
    {
        INinjectModule module = ...;//Create a module and add the ILogger here
        using (IKernel kernel = new StandardKernel(module))
        {
            var fakeLogger = kernel.Get<ILogger>(); //Get the logger  
            var book = new Book(isbn, author, title, publisher, year, pages, price, fakeLogger); 
            Console.WriteLine(book.FormatBook(book.Author, book.Publisher));
    
            return book.FormatBook(book.Author, book.Publisher);
        }
    
    }