xUnit with ASP.Net Core Web API

Hi Guys! you found this article because you wanted to integrate xUnit with a .Net Core Web API Project. In this article I will show you the following:

  • Setup xUnit to your project
  • Mock Web API
  • Fake EF Core
  • Write Unit Test 

you can find the sample project in my GitHub in the following link.

xUnitWebApiSample

Setup xUnit

First of all, you need to add a xUnit Test Project(.Net Core).

Capture

Then you need to see whether you got the right NuGet Packages. The important packages you need in your project are as follow : 

  •  xUnit packages – you don’t have to worry about this it will come with the xUnit project template. 🙂
  • Microsoft.AspNetCore.Mvc.Testing

   This reference helps you to mock the web service.

  • Microsoft.EntityFrameworkCore.InMemory
    

    To mock our entity framework. We’ll be creating our Db as an In-Memory Db.

  • Microsoft.AspNetCore.App

    Lastly, check whether you have the same version of ASP.Net Core as the Project that you are going to perform the test.

+

And also remember to reference the project you are going to test.

Mock Web API

Using WebApplicationFactory Factory you can mock the Startup class of your Web API Project. Then after that, you can override ConfigureWebHost() method and inject the classes you want to mock.

Capture.PNG

Basically, it’s like your Startup Class in your Web API project.

Fake EF Core

You can create your mock In-Memory database in your Mocked Startup class using the Db Context in your Web API Project.

// Add a database context (ApplicationDbContext) using an in-memory 
// database for testing.
services.AddDbContext<BloggingContext>(options =>
{
    options.UseInMemoryDatabase("InMemoryDbForTesting");
    options.UseInternalServiceProvider(serviceProvider);
});

There are two ways you can create In-Memory Dbs :

  • SQLite in-memory mode allows you to write efficient tests against a provider that behaves like a relational database.
  • The InMemory provider is a lightweight provider that has minimal dependencies but does not always behave like a relational database.

Write Unit Test

To your unit test class, you need to inherit IClassFixture<CustomWebApplicationFactory<Startup>>  so that you can use your mocked Web API. Once you have inherited above then you have to create a HTTPClient to access the Web API endpoints through your mocked Web API.

public class PostTest : IClassFixture<CustomWebApplicationFactory<Startup>>
   {
       public HttpClient Client { get; }
 
       public PostTest(CustomWebApplicationFactory<Startup> factory)
       {
           Client = factory.CreateClient();
       }
 
       [Fact]
       public async Task Get_Posts_ReturnPost()
       {
           // Arrange  
           int postId = 1;
 
           // Act
           var response = await Client.GetAsync($"/api/posts/{postId}");
           response.EnsureSuccessStatusCode();
 
           var stringResponse = await response.Content.ReadAsStringAsync();
           Post oPost = JsonConvert.DeserializeObject<Post>(stringResponse);
 
           // Assert
           Assert.Equal(postId, oPost.PostId);
       }
 
       [Fact]
       public async Task Post_Posts_ReturnOk()
       {
           // Arrange  
           Post oPost = new Post() { Title = "Test Title ", Content = "test content ", BlogForeignKey = 2 };
 
           // Act
           var response = await Client.PostAsJsonAsync($"/api/posts/", oPost);
           response.EnsureSuccessStatusCode();
 
           var stringResponse = await response.Content.ReadAsStringAsync();
           Post oResponsePost = JsonConvert.DeserializeObject<Post>(stringResponse);
 
           // Assert
           Assert.NotNull(oResponsePost);
       }
   }

Hope I helped you on implementing xUnit to you .Net Core Web API Project !!!! 🙂

Note: If the HTTP Context is sharing when running your xUnit tests. Configure your unit test to run sequentially.

Add the following to xunit.runner.json :

{
  "parallelizeAssembly": false,
  "parallelizeTestCollections": false,
  "diagnosticMessages": true
}

Leave a comment

I’m Harith

Enthusiastic Full Stack Software Engineer with 11 years of experience in IT and Software Development. Utilising expertise in managing all aspects of the software development lifecycle to collaborate with and guide globally dispersed cross functional Agile teams in building cutting edge software solutions across Banking, Patent Management, Healthcare, Manufacturing and Hospitality for clients in Canada, USA, Scandinavia, Australia, Malaysia and Sri Lanka. Approach situations with a solution mindset and flexibility to quickly learn new technologies, adapting to the needs and technology stack of any project to deliver high quality software solutions.

Let’s connect