Asp.Net Core Web Api Integration testing using InMemory EntityFrameworkCore Sqlite and XUnit2

Compared to unit testing, Integration testing gives us a better return on test investment.

Nowadays, we have a lot of tools to set it up easily, and it can go faster and gives us more confidence with code we have changing knowing we have not breaking existing functionalities.

It can help us to catch regression errors, before we deploy to a test environment, and fewer bugs in new features, resulting Higher velocity and higher quality solution

Unit testing test behaviour of a class and drive its implementation, run in memory and mocks the Data Access Laywer while Integration testing test the entire system and focus on interactions between many classes, uses the real database and test the Data Access Laywer and its value is to catch regressions. So Integration testing may catch errors that passes on  unit testing

In this tutorial, I will talk about Asp.Net Web Api Core Integration testing using InMemory EntityFrameworkCore Sqlite and Xunit2

So lets go ahead and implement some integration tests for the solution discussed on this tutorial Token Based Authentication using Asp.net Web Api Core

Note : InMemory is not a relational database. It is designed to be a general purpose database for testing, and is not designed to mimic a relational database.  So it will allow us to save data that would violate referential integrity constraints in a relational database.

InMemory is sufficient to test our case ( user registration and authentication)  but to test a large database, please use local DB instead of InMemory.  In my next tutorial, I’ll show how to replace InMemory with localDB

Lets start and create a XUnit Test Project using Visual Studio 2017

XunitTestProject

Add reference to the project TokenAuthWebApiCore.Server  that represent our system under test

XunitTestProject XunitTestProject2

INTEGRATION TESTING USING SQLLITE IN MEMORY

Lets install some dependencies

Dependecies1 Dependecies2 Dependecies3

Lets create a Generic TestFixture  class, here we are going to create a Test Server to  target our API  Server http://localhost:58834

So we build a host by creating an instance of WebHostBuilder.  And  our tests classes will inherits from IClassFixture<TestFixture<OurTestStartup>>

 

TestFixture

Next, open Startup.cs file of project TokenAuthWebApiCore.Server  and add 2 virtual methods SetUpDataBase and EnsureDatabaseCreated. So this 2 methods will be overriden in our test StartUp class to use a test database like SqlLite InMemory or SqlServer Local DB or any other database system

StartupVirtual

Here we are using SQLLITE, so lets create a TestStartupSqlite class that inherits from Startup

TestStartupSqlite

Next , overrides  SetUpDataBase and Configure SqlLite Inmemory, so we will use SqlLite instead of the production database

Next , overrides   EnsureDatabaseCreated to ensures that the database for the context exists. If it exists, no action is taken. If it does not exist then the database and all its schema are created.

Overrides

Next, create our first Test class AuthControllerRegisterUserTest and inherits it from IClassFixture<TestFixture<TestStartupSqlite>>

RegisterUser

Here is the implementation of  test method WhenNoRegisteredUser_SignUpWithModelError_ReturnBadRequest

RegisterUser2

Here is the implementation of  test method  WhenNoRegisteredUser_SignUp_WithValidModelState_Return_OK

RegisterUser3

Next, lets order tests methods , because to be able to get a existing user, we must register it first.   So create a PriorityOrderer class that implement ITestCaseOrderer  and  TestPriorityAttribute class and implement them as follow

TestPriority

TestPriority2 TestPriority3

Next, create our first Test class AuthControllerTokenTestand inherits it from IClassFixture<TestFixture<TestStartupSqlite>>  and implement it

Decorate test methods  with TestPriority(1)  and TestPriority(2). So  the method decorated with TestPriority(2) will be executed  after the method decorated with TestPriority(1)  that is  UserRegistration Test

AuthController_TokenTest

Thank you for reading

sample code is available here  Asp.Net-Web-Api-Core-Integration-testing-using-InMemory-EntityFrameworkCore-Sqlite-and-Xunit2

 

Gora LEYE

I’m a .NET Architect and Technical Expert skills located in Paris (FRANCE). The purpose of this blog is mainly to post general .NET tips and tricks,

  • Jon Sommervold

    Hi, and thanks for sharing this!

    This is all good for an Asp.Net Core 1.x solution, but (in my experience) once you upgrade to 2.x it all breaks.

    Seems to be some issue with the testserver, because I allways get a 404 when trying to access the api.
    This only happens when using the derived class “TestStartupSqlite”, not when using the “TokenAuthWebApiCore.Server.Startup” class directly.

    Any idea why this happens?

    Regards
    Jon S.

    • Hi, have you some redirection? if yes you must disable automatic challenge to prevent redirect on the login page that does not exist.
      if you are accessing the /api and an unauthorized request is made, do not redirect to the login page, but simply return “Unauthorized”

      • Jon Sommervold

        Hi Gora, and thanks for comming back to me!

        No, there’s no redirection occuring. I’ve been experimenting with a simple solution without any authorization at all (in addition to the project you provide here).

        If you try to convert your project to Asp.net Core 2.x and update the nuget packages accordingly, you’ll probable experience the same problems as myself.

        Give it a go – I dare you! 😉

        Regards,
        Jon S.

        • Hi, after converting project from asp.core 1.1 to asp.net Core 2.x and update nuget packages , you must also modify ConfigureServices and Configure of startup class. so example app.UseJwtBearerAuthentication(new JwtBearerOptions() must be moved from configure method and replaced by services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(….. in ConfigureServices method.

          asp.net core 2.0 introduced some breaking changes. I will upgrade and fix it soon.
          Best regards