问题
We are creating an Integration Unit test (Xunit), which is calling the Real Application Startup.cs.
For some reason, Real project can read Configuration file/property correctly, however running it from the Integration test, it cannot read it. Its not placing anything into Configuration (conf) variable below. How would I resolve this? The reason is its not picking up is its not reading the internal dependency injection new from Net Core 2.2 which reads Configuration file. Trying to use .CreateDefaultBuilder Now.
IntegrationTest1.cs
TestServer _server = new TestServer(new WebHostBuilder() .UseContentRoot("C:\\RealProject\\RealProject.WebAPI")
.UseEnvironment("Development")
.UseConfiguration(new ConfigurationBuilder()
.SetBasePath("C:\\RealProject\\RealProject.WebAPI")
.AddJsonFile("appsettings.json")
.Build())
.UseStartup<Startup>()
.UseStartup<Startup>());
Real Project Startup.cs
public Startup(IConfiguration configuration, IHostingEnvironment hostingEnvironment)
{
Configuration = configuration;
HostingEnvironment = hostingEnvironment;
}
public IHostingEnvironment HostingEnvironment { get; }
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
var conf = Configuration;
IConfiguration appConf = conf.GetSection("ConnectionStrings");
var connstring = appConf.GetValue<string>("DatabaseConnection");
services.AddDbContext<DbContext>(a => a.UseSqlServer(connstring));
Appsettings.Json
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"ConnectionStrings": {
"DatabaseConnection": "Data Source=.;Initial Catalog=ApplicationDatabase;Integrated Security=True"
}
}
回答1:
What you want to do is create a Factory for your WebApplication which takes a Startup type. You can then use the IClassFixture interface to share the context of this factory with all of your tests in your test class.
How this looks in practice is:
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup> where TStartup : class
{
public CustomWebApplicationFactory() { }
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder
.ConfigureTestServices(
services =>
{
services.Configure(AzureADDefaults.OpenIdScheme, (System.Action<OpenIdConnectOptions>)(o =>
{
// CookieContainer doesn't allow cookies from other paths
o.CorrelationCookie.Path = "/";
o.NonceCookie.Path = "/";
}));
}
)
.UseEnvironment("Production")
.UseStartup<Startup>();
}
}
public class AuthenticationTests : IClassFixture<CustomWebApplicationFactory<Startup>>
{
private HttpClient _httpClient { get; }
public AuthenticationTests(CustomWebApplicationFactory<Startup> fixture)
{
WebApplicationFactoryClientOptions webAppFactoryClientOptions = new WebApplicationFactoryClientOptions
{
// Disallow redirect so that we can check the following: Status code is redirect and redirect url is login url
// As per https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2#test-a-secure-endpoint
AllowAutoRedirect = false
};
_httpClient = fixture.CreateClient(webAppFactoryClientOptions);
}
[Theory]
[InlineData("/")]
[InlineData("/Index")]
[InlineData("/Error")]
public async Task Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(string url)
{
// Act
HttpResponseMessage response = await _httpClient.GetAsync(url);
// Assert
response.EnsureSuccessStatusCode();
}
}
I followed the guide here to get this working in my own code.
来源:https://stackoverflow.com/questions/57318131/net-core-integration-test-run-startup-cs-and-configuration-from-other-program