Zum Hauptinhalt springen

Api integration testing in Csharp

first some basic examples

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapGet("/sum", (int? n1, int? n2) => n1 + n2);
app.Run();
public class SimpleTesting{
[TestMethod]
public async Task DefaultRoute_ReturnsHelloWorld(){
var webAppFactory = new WebApplicationFactory<Program>();
_httpClient = webAppFactory.CreateDefaultClient();
var response = await _httpClient.GetAsync("");
string result = await response.Content.ReadAsStringAsync();
Assert.AreEqual("Hello World!", result);
}

[TestMethod]
public async Task Sum_Returns24(){
var webAppFactory = new WebApplicationFactory<Program>();
_httpClient = webAppFactory.CreateDefaultClient();
var response = await _httpClient.GetAsync("/sum?n1=10&n2=14");
int result = await response.Content.ReadAsStringAsync();
Assert.AreEqual(16, result);
}
}

An more involved testing scenario

For a theoretical Api that does some Auth, uses JWT etc...

Packages used:

  • Microsoft.AspNetCore.Mvc.Testing
  • Microsoft.AspNetCore.App

IntegrationTest.cs

public class IntegrationTest
{
protected readonly HttpClient TestClient;

protected IntegrationTest(){
var appFactory = new WebApplicationFactory<Startup>()
.WithWebHostBuilder(builder =>
{
builder.ConfigureServices(services =>
{
services.RemoveAll(typeof(DataContext));
services.AddDbContext<DataContext>(options => { options.UseInMemoryDatabase("TestDb"); });
});
});

TestClient = appFactory.CreateClient();
}

protected async Task AutenticateAsync(){
TestClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", await GetJwtAsync());
}

protected async Task<PostResponse> CreatePostAsync(CreatePostRequest request){
var response = await TestClient.PostAsJsonAsync(ApiRoutes.Posts.Create, request);
return await response.Content.ReadAsAsync<PostResponse>();
}

private async Task<string> GetJwtAsync(){
var response = await TestClient.PostAsJsonAsync(ApiRoutes.Identity.Register, new UserRegistrationRequest{
Email = "test@integration.com",
Password = "SomePass1234!"
});

var registrationResponse = await response.Content.ReadAsAsync<AuthSuccessResponse>();
return registrationResponse.Token;
}
}

PostsControllerTests.cs

public class PostsControllerTests : IntegrationTest{
[Fact]
public async Task GetAll_WithoutAnyPosts_ReturnsEmptyResponse(){
// Arrange
await AutenticateAsync();

// Act
var response = await TestClient.GetAsync(ApiRoutes.Posts.GetAll);

// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
(await response.Content.ReadAsAsync<List<Post>>()).Should().BeEmpty();
}

[Fact]
public async Task Get_ReturnsPost_WhenPostExistsInTheDatabase(){
// Arrange
await AutenticateAsync();
var createdPost = await CreatePostAsync(new CreatePostRequest {Name = "Test post"});

// Act
var response = await TestClient.GetAsync(ApiRoutes.Posts.Get.Replace("{postId}", createdPost.Id.ToString()));

// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var returnedPost = await response.Content.ReadAsAsync<Post>();
returnedPost.Id.Should().Be(createdPost.Id);
returnedPost.Name.Should().Be("Test post");
}
}