Posts

How to unit test if all required dependencies have been registered

 Hi, 

I am currently implementing prism.js on pixelencounter.com for that I will use this post with some C# code to try it out. I have decided I will write some code on how to unit test required business logic dependencies so they are registered in the container.

The code below is an example, it will help me to not forget to register services.


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using FluentAssertions;
using Tutorial.BusinessLogic.Extensions;
using Tutorial.BusinessLogic.Interfaces.Battles;
using Tutorial.BusinessLogic.Stores;
using Tutorial.Core.Extensions;
using Tutorial.Core.Models.Identity;
using Tutorial.Infrastructure.BackgroundWorker;
using Tutorial.Infrastructure.Entity;
using Tutorial.Infrastructure.Extensions;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Hosting.Internal;
using Xunit;
using BusinessLogicSharedResource = Tutorial.BusinessLogic.SharedResource;

namespace Tutorial.Tests.PixelEncounter
{
public class ServiceCollectionTest
{
internal class TestApplication
{
private readonly ApplicationDbContext _db;

public TestApplication(ApplicationDbContext db)
{
_db = db;
}

public bool CanInject()
{
return _db != null;
}
}

[Fact]
public void BuildServiceProviderInjectedDepedency()
{
IServiceCollection services = CreateServices();
services.AddSingleton<TestApplication>();
using var sut = services.BuildServiceProvider();
var application = sut.GetRequiredService<TestApplication>();
application.CanInject().Should().BeTrue();
}

[Fact]
public void GetServicesReturnAllBusinessLogicServices()
{
IServiceCollection services = CreateServices();
using var sut = services.BuildServiceProvider();

var serviceTypes = GetInterfaceTypesForBusinessLogicServices();
foreach (var serviceType in serviceTypes)
{
var service = sut.GetRequiredService(serviceType);
service.Should().NotBeNull();
}
}

private static IEnumerable<Type> GetInterfaceTypesForBusinessLogicServices()
{
var blackList = new Type[]
{
typeof(ITestAbstractService)
};

return GetInterfaceTypesForServices(typeof(BusinessLogicSharedResource), blackList);
}

private static IEnumerable<Type> GetInterfaceTypesForServices(Type assemblyType, params Type[] blacklist)
{
var ns = assemblyType.Namespace;
var query = from t in Assembly.GetAssembly(assemblyType).GetTypes()
where t.IsInterface && t.Namespace.StartsWith($"{ns}.Interfaces")
select t;

if (blacklist?.Length > 0)
{
query = query.Where(t => !blacklist.Any(b => b.Equals(t)));
}

return query;
}

private static IConfiguration SetupConfiguration()
{
return new ConfigurationBuilder()
.SetBasePath(Directory.GetParent(AppContext.BaseDirectory).FullName)
.AddJsonFile("appsettings.json", true)
.AddUserSecrets<Program>()
.Build();
}

private static IServiceCollection CreateServices()
{
var configuration = SetupConfiguration();

IServiceCollection services = new ServiceCollection();
services.AddSingleton(configuration);
services.AddLogging();
services.AddLocalization();

var env = new HostingEnvironment { EnvironmentName = Environments.Development };
services.AddSingleton<IHostEnvironment>(env);

services.AddDbContextPool<ApplicationDbContext>(option =>
{
option.UseInMemoryDatabase(nameof(ServiceCollectionTest));
});

services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddUserStore<ApplicationUserStore>()
.AddDefaultTokenProviders();

services.AddOptions();
services.AddDistributedMemoryCache();
services.AddHostedService<QueuedHostedService>();

services.AddCore();
services.AddInfrastructure();
services.AddConfiguratedAutoMapperProfiles();
services.AddBusinessLogic();

return services;
}
}
}

View on blog

Last updated: 2021-09-13 11:22

The date after the article title is the published date. Each post may have tag links which can be used to filter the posts.