I am following this guide. I have a Startup
in the API project that uses an appsettings.json
configuration file.
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.ReadFrom.Configuration(Configuration)
.CreateLogger();
}
The particular part I'm looking at is the env.ContentRootPath
. I did some digging around and it looks like my appsettings.json
isn't actually copied to the bin
folder but that is fine as ContentRootPath
is returning MySolution\src\MyProject.Api\
, which is where the appsettings.json
file is located.
So in my integration test project I have this test:
public class TestShould
{
private readonly TestServer _server;
private readonly HttpClient _client;
public TestShould()
{
_server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
_client = _server.CreateClient();
}
[Fact]
public async Task ReturnSuccessful()
{
var response = await _client.GetAsync("/monitoring/test");
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
Assert.Equal("Successful", responseString);
}
This is basically copy and paste from the guide. When I debug this test, ContentRootPath
is actually MySolution\src\MyProject.IntegrationTests\bin\Debug\net461\
, which is obviously the build output folder for the test project and again the appsettings.json
file is not there (yes I do have another appsettings.json
file in the test project itself) so the test fails at creating the TestServer
.
I tried getting around this by modifying the test project.json
file.
"buildOptions": {
"emitEntryPoint": true,
"copyToOutput": {
"includeFiles": [
"appsettings.json"
]
}
}
I hoped this would copy the appsettings.json
file to the build output directory but it complains about the project missing a Main
method for an entry point, treating the test project like a console project.
What can I do to get around this? Am I doing something wrong?
Integration test on ASP.NET.Core 2.0 follow MS guide ,
You should right click appsettings.json
set its property Copy to Output directory
to Copy always
And now you could find the json file in output folder, and build TestServer
with
var projectDir = GetProjectPath("", typeof(TStartup).GetTypeInfo().Assembly);
_server = new TestServer(new WebHostBuilder()
.UseEnvironment("Development")
.UseContentRoot(projectDir)
.UseConfiguration(new ConfigurationBuilder()
.SetBasePath(projectDir)
.AddJsonFile("appsettings.json")
.Build()
)
.UseStartup<TestStartup>());
/// Ref: https://stackoverflow.com/a/52136848/3634867
/// <summary>
/// Gets the full path to the target project that we wish to test
/// </summary>
/// <param name="projectRelativePath">
/// The parent directory of the target project.
/// e.g. src, samples, test, or test/Websites
/// </param>
/// <param name="startupAssembly">The target project's assembly.</param>
/// <returns>The full path to the target project.</returns>
private static string GetProjectPath(string projectRelativePath, Assembly startupAssembly)
{
// Get name of the target project which we want to test
var projectName = startupAssembly.GetName().Name;
// Get currently executing test project path
var applicationBasePath = System.AppContext.BaseDirectory;
// Find the path to the target project
var directoryInfo = new DirectoryInfo(applicationBasePath);
do
{
directoryInfo = directoryInfo.Parent;
var projectDirectoryInfo = new DirectoryInfo(Path.Combine(directoryInfo.FullName, projectRelativePath));
if (projectDirectoryInfo.Exists)
{
var projectFileInfo = new FileInfo(Path.Combine(projectDirectoryInfo.FullName, projectName, $"{projectName}.csproj"));
if (projectFileInfo.Exists)
{
return Path.Combine(projectDirectoryInfo.FullName, projectName);
}
}
}
while (directoryInfo.Parent != null);
throw new Exception($"Project root could not be located using the application root {applicationBasePath}.");
}
Ref: TestServer w/ WebHostBuilder doesn't read appsettings.json on ASP.NET Core 2.0, but it worked on 1.1