I am currently using Xunit to write some integration testing in my .NET Core project. As part of this, I am setting up the data and other information before running a test in my custom class.
using Microsoft.AspNetCore.TestHost;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace XUnitTestProject1
{
public class BaseClassFixture<TStartup> : IAsyncLifetime where TStartup : class
{
private readonly TestServer _server;
public HttpClient Client { get; }
public BaseClassFixture()
{
Client = new HttpClient();
Client.BaseAddress = new Uri("https://apple.com");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_server?.Dispose();
this.Client?.Dispose();
}
}
public Task DisposeAsync()
{
return Task.CompletedTask;
}
public Task InitializeAsync()
{
throw new NotImplementedException();
}
}
}
My first Child Class:
using Microsoft.AspNetCore.TestHost;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace XUnitTestProject1
{
public class GoogleTestClassFixture<TStartUp> : BaseClassFixture<TStartUp>, IAsyncLifetime where TStartUp : class
{
private readonly TestServer _server;
public HttpClient GoogleClient { get; }
public GoogleTestClassFixture()
{
GoogleClient = new HttpClient();
GoogleClient.BaseAddress = new Uri("https://google.com");
GoogleClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public void Dispose()
{
_server?.Dispose();
GoogleClient?.Dispose();
base.Dispose(true);
}
public Task DisposeAsync()
{
throw new NotImplementedException();
}
public Task InitializeAsync()
{
throw new NotImplementedException();
}
}
}
My Second Child Class:
using Microsoft.AspNetCore.TestHost;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace XUnitTestProject1
{
public class FaceBookTestClassFixture<TStartUp> : BaseClassFixture<TStartUp>, IAsyncLifetime where TStartUp : class
{
private readonly TestServer _server;
public HttpClient FaceBookClient { get; }
public FaceBookTestClassFixture()
{
FaceBookClient = new HttpClient();
FaceBookClient.BaseAddress = new Uri("https://facebook.com");
FaceBookClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public void Dispose()
{
_server?.Dispose();
FaceBookClient?.Dispose();
base.Dispose(true);
}
public Task DisposeAsync()
{
throw new NotImplementedException();
}
public Task InitializeAsync()
{
throw new NotImplementedException();
}
}
}
When I run all the tests in my test explorer at once, some times I'm getting the error "Cannot access a dispose object". I am assuming, this is happening because some times the tests related to one test fixture are running and the object is disposed, and the other test fixture is unable to access already disposed of items from the base Class fixture.
My First Tests looks something like this:
public class GoogleTests
{
private readonly HttpClient _googleClient;
private readonly HttpClient _baseClient;
public GoogleTests(GoogleTestClassFixture<StartUp> fixture)
{
_googleClient = fixture.GoogleClient;
_baseClient = fixture.Client;
}
[Fact]
public async Task ValidateFirstClient()
{
var getDetails = await _googleClient.GetAsync("//someRoute");
var uri = new Uri("https://someRandom.com");
var postDetails = await _baseClient.PutAsync(uri, getDetails.Content);
var response = await postDetails.Content.ReadAsStringAsync();
dynamic dynamicResponse = JObject.Parse(response);
((int)dynamicResponse.myProperty).Should().Be(0);
}
}
My Second Test Class:
using FluentAssertions;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace XUnitTestProject1
{
public class FaceBookTests
{
private readonly HttpClient _fbClient;
private readonly HttpClient _baseClient;
public FaceBookTests(FaceBookTestClassFixture<StartUp> fixture)
{
_fbClient = fixture.FaceBookClient;
_baseClient = fixture.Client;
}
[Fact]
public async Task ValidateFirstClient()
{
var getDetails = await _fbClient.GetAsync("//someRoute");
var uri = new Uri("https://someRandom.com");
var postDetails = await _baseClient.PutAsync(uri, getDetails.Content);
var response = await postDetails.Content.ReadAsStringAsync();
dynamic dynamicResponse = JObject.Parse(response);
((int)dynamicResponse.myProperty).Should().Be(0);
}
}
}
enter code here
How can I solve this issue, and make sure the object is not disposed until it finishes running all the tests? Note: I have created a simple web application project just to get the startup.cs class as a reference in my test project