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

Version 1.0.7 - Location and My Statistics

  • The location will have an elemental affinity by most monster. 
  • Various bugfixes.
  • Added my statistics page.
  • Balanced battle.

View on blog

Last updated: 2021-09-12 22:37

Version 1.0.6 - Monster Battles

  • Added SVG monster on fought monsters
  • Added SVG monster on battle result dialog
  • Fixed issue where one extra round is triggered after the victim is fallen.

View on blog

Last updated: 2021-09-12 22:37

Welcome

Hello, 

Welcome to our blog Pixel Encounter. Our API can be used for free to generate SVG monsters.

We will use this blog to post news about new releases of the Pixel Encounter API and the game. This is our first post on blogger and it will be used as a feed on our homepage.

View on blog

Last updated: 2021-08-27 16:53

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