I am new to integration testing. My .Net 7 WebApi uses Hangfire and it is failing to build when the CustomWebApplicationFactory is called. I am using xUnit to do the tests.
public class CustomWebApplicationFactory : WebApplicationFactory<Program>
{
public Mock<IAnimals> animals { get; }
public CustomWebApplicationFactory()
{
animals = new Mock<IAnimals>();
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
base.ConfigureWebHost(builder);
builder.ConfigureTestServices(services =>
{
services.AddSingleton(animals.Object);
services.AddLogging(builder => builder.AddConsole().AddDebug());
});
}
}
The error I get is:
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.TestHost.dll
An exception of type 'System.InvalidOperationException' occurred in
Microsoft.AspNetCore.TestHost.dll but was not handled in user code
The server has not been started or no web application was configured.
My logging statement services.AddLogging() outputs this as the error:
Exception thrown: 'System.InvalidOperationException' in Hangfire.PostgreSql.dll
In program.cs my hangfire config is:
var connectionString = builder.Configuration.GetConnectionString("PostgreSQLConnection");
builder.Services.AddHangfire(config => config
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseStorage(new PostgreSqlStorage(connectionString)
));
Any help is appreciated!
I don't really intend to test the Hangfire jobs, but I do need to test other services. Is there a way to get hangfire to build (maybe an in-memory database?) or to just mock hangfire or skip it?
Update:
I have tried to configure Hangfire and Entity as in-memory databases... something is still not quite right...
builder.ConfigureServices(services => {
// Configure Entity In-Memory database
services.RemoveAll(typeof(AppDbContext));
services.AddDbContext<AppDbContext>(opt => opt.UseInMemoryDatabase(databaseName: "IntegrationTestDb_" + DateTime.Now.ToFileTimeUtc()));
services.RemoveAll(typeof(GlobalConfiguration));
services.AddHangfire(config => config
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseMemoryStorage());
});
I have run in to the same problem recently, and end up with this solution:
var hangfireGiblets = collection
.Where(s => s
.ServiceType.FullName
?.Contains("hangfire", StringComparison.InvariantCultureIgnoreCase) == true)
.ToArray();
foreach (var hangfirePart in hangfireGiblets)
{
collection.Remove(hangfirePart);
}
collection.AddSingleton(Mock.Of<IGlobalConfiguration>())
.AddSingleton(Mock.Of<JobStorage>())
.AddSingleton(Mock.Of<IUpdateVendorDataJobsScheduler>())
.AddSingleton(Mock.Of<RouteCollection>());