- Home
- .NET tutorials
- Four useful tips when using ASP.NET Core's TestServer in xUnit: TestServer - Part 2
Four useful tips when using ASP.NET Core's TestServer in xUnit: TestServer - Part 2
Published: Wednesday 25 November 2020
We are going to have a look at four useful tips when using ASP.NET Core's TestServer in a xUnit project.
Tip #1: TestServer's DbContext Instance
By default, when adding a DbContext into dependency injection, the default service lifetime is scoped.
// Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
...
public void ConfigureServices(IServiceCollection services)
{
...
services.AddDbContext<CrudApiDbContext>(options =>
{
options.UseInMemoryDatabase("MyDatabase-" + Guid.NewGuid());
}, ServiceLifetime.Singleton);
...
}
...
}
Tip #2: Post Request on TestServer
Our second tip will look at how we can call a post request on TestServer.
// UnitTest1.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using System;
using System.Net;
using System.Threading.Tasks;
using Xunit;
using System.Net.Http;
using System.Collections.Generic;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Text;
public class UnitTest1 : IDisposable
{
protected TestServer _testServer;
public UnitTest1()
{
var webBuilder = new WebHostBuilder();
webBuilder.UseStartup<Startup>();
_testServer = new TestServer(webBuilder);
}
[Fact]
public async Task TestCreateMethod()
{
var request = new HttpRequestMessage(HttpMethod.Post, "/api/league");
request.Content = new StringContent(JsonConvert.SerializeObject(new Dictionary<string, string>
{
{"Name", "MyLeague"}
}), Encoding.Default, "application/json");
var client = _testServer.CreateClient();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.SendAsync(request);
response = await _testServer.CreateRequest("/api/league/1").SendAsync("GET");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
...
public void Dispose()
{
_testServer.Dispose();
}
}
Tip #3: Add Authorization Header into a TestServer Request
Adding an authorization header into a TestServer request is relatively straight forward.
response = await _testServer.CreateRequest("/api/league/2").AddHeader("Authorization", "bearer {token}").SendAsync("GET");
And it's a similar story if we are doing a POST request. Once we have created the request, we can call an instance of Headers and use the Add method from it.
// UnitTest1.cs
public class UnitTest1 : IDisposable
{
...
[Fact]
public async Task TestCreateMethod()
{
var request = new HttpRequestMessage(HttpMethod.Post, "/api/league");
request.Headers.Add("Authorization", "bearer {token}");
...
}
...
}
Tip #4: Use The Same Instance of TestServer in All Tests
By default, every time we run a test, it creates a new instance of that test before running it.
// Initialisation.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
namespace RoundTheCode.CrudApi.Tests
{
public class Initialisation
{
public TestServer TestServer { get; }
public Initialisation()
{
var webBuilder = new WebHostBuilder()
.UseStartup<Startup>();
TestServer = new TestServer(webBuilder);
}
}
}
// UnitTest1.cs
namespace RoundTheCode.CrudApi.Tests
{
public class UnitTest1 : IDisposable, IClassFixture<Initialisation>
{
protected TestServer _testServer;
public UnitTest1(Initialisation initialisation)
{
_testServer = initialisation.TestServer;
}
...
}
}
This means that every time a test is called in UnitTest1, it calls the instance of Initalisation.
Bonus Tip: Add appsettings.json to xUnit Project
Watch our ASP.NET Core coding tutorial where we give a bonus tip of how we can add a custom AppSettings.json file to our xUnit project.
In-addition, we will show the other four tips mentioned in this article, such as creating a POST request in TestServer, and how to add an Authorization header to your TestServer request.
Related tutorials