Integration Testing of Event-Driven microservices ⚙️🐳

ExecuteAutomation
ExecuteAutomation
Published in
4 min readJan 25, 2023

A microservice can be a UI, API, DB or even a message broker, they might be running in an containers deployed in either AWS, Azure or any cloud providers or even your local docker cloud.

These microservices might be independent to each other communicating with each other via Message broker like RabbitMq or Kafka via Publisher/Subscriber model using Event-Driven architecture or sometimes even consuming other microservices for API access from UI layer.

Now the question is, how do we test these event-driven microservices and whats the better approach to test them via Integration testing

If you have read my earlier post on “Testing Event-Driven Microservices with C# .NET” you will already know what exactly I am going to talk about here a bit.

Integration testing

Integration tests ensure that an app’s components function correctly at a level that includes the app’s supporting infrastructure, such as the

  • Database 📀,
  • File system 📁,
  • Network 🌏
  • Request-response pipeline

Integration testing can be done between each and every of the component level rather the whole application infrastructure available at any given time, meaning, only targeted services and its dependencies needs to be present.

Applications Component ⚡️

Lets assume we wanted to test the applications API controllers functionality of our service CustomerService. To test the API controllers CRUD operation we need to ensure there are proper data in database.

As you can see here our component under test is the API service controllers NOT the Database.

Integration test for WebAPI Controllers of service NOT database

But in order for the above operation to happen in an isolated context, where we just need to invoke the Service Under Test (which is ConsumerService in this case) and Database Server with related entities in it and we don’t require any other microservices whatsoever.

How do we achieve Isolated Context of Application via Integration test ?

The power of ASP.NET or any other framework even Springboot in Java is that, there are ways to run an application or service In-memory context. This way, we can run our Service Under Test and Database in seperate isolated context via In-Memory rather deploying the application in any microservice container which need other ceremonies like configurations.

So, in C# .NET world, we can do this with the help of WebApplicationFactory class available in Microsoft.AspNetCore.Mvc.Testing nuget package.

The above explanation in the code is going to look like this

[Fact]
public async Task Test1()
{
using var client = _testFixtureWithDatabaseSetup.CreateDefaultClient();

var response = await client.GetAsync("/products");

var result = await response.Content.ReadAsStringAsync();

result.Should().NotBeNullOrEmpty();

_testOutputHelper.WriteLine(result);
}

As you can see in the above code, the _testFixtureWithDatabaseSetup class is responsible for creating the InMemory context of our CustomerService WebAPI. It also does following

  1. Create In-Memory context of our service
  2. Create In-Memory database
  3. Ensure Database is created (based on the DbContext)
  4. Also creates the data within the tables
public class TestFixtureWithDatabaseSetup<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
base.ConfigureWebHost(builder);

builder.ConfigureTestServices(services =>
{

var descriptor =
services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<CustomerDbContext>));

if(descriptor is not null)
services.Remove(descriptor);

services.AddDbContext<CustomerDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryCustomerDb");
});

var sp = services.BuildServiceProvider();
using var scope = sp.CreateScope();
using var appContext = scope.ServiceProvider.GetRequiredService<CustomerDbContext>();
appContext.Database.EnsureDeleted();
appContext.Database.EnsureCreated();

//Seed the data for the API service to be tested
var products = new Product
{
Id = 1,
Name = "Keyboard",
Quantity = 100,
ProductId = Guid.NewGuid()
};

appContext.Products.Add(products);
appContext.SaveChanges();
});
}

public override async ValueTask DisposeAsync()
{
await Task.Run(() =>
{
Task.Delay(2500);
base.DisposeAsync();
});
}
}

Complete Test class to verify API Controllers

So, the complete Test class to test the API controllers, atleast one of the GET controller is going to look like this

Collection("IntegrationTests")]
public class SimpleApiTestWithSeedData : IClassFixture<TestFixtureWithDatabaseSetup<Program>>
{
private readonly TestFixtureWithDatabaseSetup<Program> _testFixtureWithDatabaseSetup;
private readonly ITestOutputHelper _testOutputHelper;

public SimpleApiTestWithSeedData(TestFixtureWithDatabaseSetup<Program> testFixtureWithDatabaseSetup, ITestOutputHelper testOutputHelper)
{
_testFixtureWithDatabaseSetup = testFixtureWithDatabaseSetup;
_testOutputHelper = testOutputHelper;
}

[Fact]
public async Task Test1()
{
using var client = _testFixtureWithDatabaseSetup.CreateDefaultClient();

var response = await client.GetAsync("/products");

var result = await response.Content.ReadAsStringAsync();

result.Should().NotBeNullOrEmpty();

_testOutputHelper.WriteLine(result);
}
}

As you can see, we are using the IClassFixture to create the instance of TestFixtureWithDatabaseSetup class.

This way, we can ensure we can test each and every component of our Microservices via Integration tests in much robust manner.

Complete Course and more details

This whole article is part of my course in Udemy, where I have covered even more details related to all the testing approaches that we have discussed about in this article

Course in Udemy

https://www.udemy.com/course/testing-eda-microservices/

If you think this course is something for you and wanted to enrol, do send out an email to karthik@techgeek.co.in or comment below, will send you the latest coupon code of discount.

Here is the launch coupon code which will valid till 29th of next year Jan 2022 EA_LAUNCH_23

--

--

ExecuteAutomation
ExecuteAutomation

ExecuteAutomation Ltd is a Software testing and its related information service company founded in 2020. Info available in YouTube and Udemy as video courses .