While I will concede that integration testing with an in-memory database is the most thorough and safe way to work, my specific situation would make this aspect extremely difficult and time consuming. I am using a hosted SQL development server that I overwrite after a period of tests. I worked for several days and found the below to be the process that gave me the results I was looking for.
- DotNet Core 2.1
- Hexagonal (Onion) architecture needing to test the business logic written in my Data
Access Layer
Program.CS file I added:
//for integration testing
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services => services.AddAutofac())
.UseStartup<Startup>();
My Integration Test File:
using Core.Data.Entities.Model;
using Core.Data.Entities.UTIA;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Profile.Data.Repos;
using Profile.Domain.DomainObjects;
using Super2.Web;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
namespace Profile.Test
{
public class EmployeeProfileIntegrationTest : IClassFixture<WebApplicationFactory<Startup>>
{
private readonly HttpClient _client;
public EmployeeProfileIntegrationTest(WebApplicationFactory<Startup> factory)
{
_client = factory.CreateClient();
}
private DBContext GetContext()
{
var options = new DbContextOptionsBuilder<DBContext>()
.UseSqlServer("Server = 'Connection String from appsettings'")
.Options;
var context = new DBContext(options);
return context;
}
[Fact]
public async Task TestChildProtectionEmployeeGetData()
{
//Arrange
var ApplicationUserId = XXXX;
var repo = new EmployeeProfileRepo(GetContext());
//ACT
var sut = await repo.GetChildProtectionHistory(ApplicationUserId);
//Assert
var okResult = sut.Should().BeOfType<List<DomainObject>>().Subject;
okResult.First().ApplicationUserId.Should().Be(XXXX);
}
}
}
While I am injecting my context into a different layer, I would suspect that it would work the same for a controller. I included the startup snippet as this caused me some issues as the testserver was looking for IWebHostBuilder instead of the default Core2.1 IWebHost.
Either way, this worked for me. Hope you can get some help from this.