.Net Core, Unit Testing and Dependency Injection

Hi there. If you found this page in the hope I have a published, easy to use guide on how to do Unit Testing and DI in .Net Core. Really sorry to disappoint. I am hoping that some kind soul finds this blog and shows me how it is far easier in .Net Core - but I doubt it.

You aren't even using Unit Testing!

Those reading this post will see that what I am trying to do is to run integration tests. That's right, no faking going on.

The .Net Framework

In the old days, which in many ways are the current days, I used to use something like the following for unit testing;

Requirement  Possible Frameworks  Comments 
 Dependency Injection Ninject  Awesome, generic wildcard resolution and advanced structure setup for different scoped object lifespans. 
 Unit Testing NUnit, XUnit Brilliant libraries capable of having parameterised tests, assisting with Asynchronous Unit Testing. 
 Mocking, Faking, Stubbing FakeItEasy  Brilliant library to help other developers understand what you are coding. L:
Logging NLog Used this on client sites and has a lot of flexibility.

Why use Dependency Injection?

This is not the lowdown on what DI is or why to use it. Instead, why do I use Dependency Injection? Mainly, I use DI to reduce the amount of wiring up and composition I do within classes. I cannot claim it to always be true, but I find that the whole code base becomes simpler, less entangled and removes a certain amount of clutter from objects. 

This means I will even use DI when I know there will only be one object implementing that contract.

Why use Unit Testing?

Again - I don't profess to extol the virtues of UT. Often, it is unnecessary, overbearing, doesn't add quality to the code base, and slows down development. However, unit testing is great for proving calculations works, and showing other developers how some procedural based invocation works. I took Unit Testing to quite a high level of understanding off-site but would never do this to that level on-site because many clients are rarely prepared for true unit testing.

I tend to use unit testing for the following reasons;

  • To demonstrate calculations.
  • As proof of concept, understanding approaches.
  • To show how to use an object. i.e. Open a connection and to retrieve data.

In short, you will see terrible code coverage stats in many of my projects.

Unit testing and Dependency Injection

Rightly or wrongly, I tend to build console/web applications using interfaces rather than concrete implementations. This permits using Dependency Injection within Unit tests to refer to the same contracts/interfaces, but to switch to fakes if required.

.Net Core

.Net Core is 75% good and 25% bad. Loads of great new features, improved speed and seemingly reasonable compatibility with previous .Net versions. The main challenge I see is - how the hell do you hope to get to the same level of ability when it comes to Unit Testing, Logging and Dependency Injection.

At the moment, I have moved my websites to .Net Core and I am running with even fewer unit tests. The reason being, I have to spend quite a bit of time translating how I used to do DI and UT, and was going to need to compose objects or create some base classes to inherit inside the unit test classes.

What seems to have happened is .Net Core has focused on building the bus but forgot their passengers.

Many existing Dependency Injection frameworks don't work with .Net Core. Research shows that Autofac does, Ninject doesn't.

Got it working - not perfect

Spent a little time playing around. Did some thinking and went to good old Stack Overflow for inspiration. It works but it is ugly.

using IRBusinessLayer.Infrastructure;
using IRCodeGenerator.Business.IRCodeGenerator.Application;
using IRCodeGenerator.Infrastructure;
using IRDataManager.Data;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Text;
namespace IRTest.CodeGenerator
{
    [TestFixture]
    public class TestGettingData
    {
        private ServiceProvider serviceProvider { get; set; }
        [SetUp]
        public void SetUp()
        {
            var services = new ServiceCollection();
            services.AddTransient<IDataRepositoryManager, DataRepositoryManager>();
            services.AddTransient(typeof(IClassMapper<,>), typeof(ClassMapper<,>));
            services.AddTransient<IParameterBuilder, ParameterBuilder>();
            services.AddTransient<ParameterAdder>();
            services.AddTransient<ParameterFactory>();
            services.AddTransient<string>();
           
            Dictionary<string, ParameterFactory> param = new IRCodeGenerator.Data.Configuration().ConfigOfDataManagement;
            services.AddSingleton(param);
                      
            services.AddTransient<TemplateGenerator>();
            serviceProvider = services.BuildServiceProvider();
        }
        [TearDown]
        public void TearDown()
        {
        }
        [Test]
        public void TestGetingtData()
        {
 
            var dataRetriever = serviceProvider.GetService<TemplateGenerator>();
...
        }
    }
}

 

https://stackoverflow.com/questions/37724738/how-to-unit-test-asp-net-core-application-with-constructor-dependency-injection

Update - this could be the clue... https://stackify.com/net-core-dependency-injection/ 

Add comment