Automated testing is highly important. It helps not only to keep your code working after some changes but also makes easier the process of writing the code (TDD).
There are several approaches of testing ASP.NET Core MVC applications. The simplest one is just to create an instance of controller and call its methods in the test:
public class SomeControllerTests
{
[Test]
public async Task GetAll_ShouldReturnAll()
{
// Arrange
var service = new SomeService();
var controller = new SomeController(service);
// Act
var result = controller.GetAll();
// Assert
// TODO check result
}
}
But this approach has several problems:
- You need to create controller with all dependencies
- You don't test HTTP part (routing, status codes, serialization)
These problems could be solved using Microsoft.AspNetCore.TestHost nuget.
public class TestFixture
{
public HttpClient HttpClient { get; private set; }
public async Task Initialize()
{
var builder = new HostBuilder()
.ConfigureWebHost(webHost =>
{
webHost.UseTestServer();
webHost.UseStartup<Startup>();
ConfigureWebHost(webHost);
});
_host = await builder.StartAsync();
HttpClient = _host.GetTestClient();
}
private void ConfigureWebHost(IWebHostBuilder builder)
{
IConfigurationRoot configurationRoot = null;
builder.ConfigureAppConfiguration((context, conf) =>
{
conf.AddJsonFile("appsettings.json");
configurationRoot = conf.Build();
});
builder.ConfigureTestServices(services =>
{
// Here you can overwrite some services
});
}
}
You also need a small class which will help to serialize request models:
public class JsonContent : ByteArrayContent
{
public JsonContent(object obj) : base(ConvertToBytes(obj))
{
Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
private static byte[] ConvertToBytes(object obj)
{
var serialized = JsonConvert.SerializeObject(obj);
return Encoding.UTF8.GetBytes(serialized);
}
}
Now you can create fake http host in your tests:
public class SomeControllersTests
{
private TestFixture _sut;
[SetUp]
public async Task Setup()
{
_sut = new TestFixture();
await _sut.Initialize();
}
[Test]
public async Task GetAll_ShouldReturnAll()
{
// Act
var request = new SomeRequest
{
// Some request data
}
var response = await _sut.HttpClient.PostAsync($"some-route", new JsonContent(request));
// Assert
// TODO check response
}
}
Also you can add required authorization by manipulating with HttpClient.
GLHF
Top comments (0)