英文:
ProblemDetails don't work when the application is started via a WebApplicationFactory (i.e in an integration test)
问题
我有一个已正确配置为在任何未处理异常时返回ProblemDetails的ASP.NET Core应用程序。这按预期工作,异常被抛出,响应是带有预期的ProblemDetails JSON主体的HTTP500。然而,如果将相同的应用程序作为集成测试的一部分使用WebApplicationFactory<Program>
启动,那么在同一失败的请求主体中将不会返回ProblemDetails。整个ProblemDetails机制似乎停止运行。这似乎是一个bug,但我想知道是否有人让这个工作,或者是否有任何解决方法?
供参考,ProblemDetails在Program.cs
中启用如下:
services.AddProblemDetails()
app.UseExceptionHandler()
英文:
I have an ASP.NET Core application that is correctly configured to return ProblemDetails upon any unhandled exaception. This works as expected, exception is thrown and the response is a HTTP500 with the expected ProblemDetails JSON body. However, if the same application is spun up as part of a integration test using WebApplicationFactory<Program>
, ProblemDetails are not returned in the same failed request body. The whole ProblemDetails mechanism just seems to stop functioning. This seems like a bug but I'm curious if anyone has this working or if there are any workarounds?
For reference, ProblemDetails are enabled in Program.cs
with;
services.AddProblemDetails()
app.UseExceptionHandler()
答案1
得分: 0
也许你正在使用 XUnit
,它不直接支持控制台输出,但你可以使用 try...catch...
来获取错误消息。
例如:
BasicTests:
public class BasicTests
: IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;
ITestOutputHelper output;
public BasicTests(WebApplicationFactory<Program> factory, ITestOutputHelper output)
{
_factory = factory;
this.output= output;
}
[Theory]
[InlineData("/About")]
public async Task Get_EndpointsReturnSuccessAndCorrectContentType(string url)
{
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync(url);
// Assert
try
{
//不要使用这一行
//response.EnsureSuccessStatusCode(); // Status Code 200-299
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
catch (XunitException e)
{
output.WriteLine(e.InnerException.Message);
}
}
}
About:
public async Task<IActionResult> OnGet()
{
throw new NullReferenceException();
}
另一种方法是不使用 XUnit
,而是使用 NUnit
或 MSTest
。以 MSTest 为例:
UnitTest1:
[TestClass]
public class UnitTest1
{
private HttpClient _httpClient;
public UnitTest1()
{
var webAppFactory = new WebApplicationFactory<Program>();
_httpClient = webAppFactory.CreateDefaultClient();
}
[TestMethod]
public async Task WeatherForcast()
{
var response = await _httpClient.GetAsync("/WeatherForecast");
var stringResult = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
}
}
Api:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
throw new NullReferenceException();
}
}
英文:
Maybe you're using XUnit
, which doesn't directly support console output, but you can use try...catch...
to get error messages.
For example:
BasicTests:
public class BasicTests
: IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;
ITestOutputHelper output;
public BasicTests(WebApplicationFactory<Program> factory, ITestOutputHelper output)
{
_factory = factory;
this.output= output;
}
[Theory]
[InlineData("/About")]
public async Task Get_EndpointsReturnSuccessAndCorrectContentType(string url)
{
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync(url);
// Assert
try
{
//don't use this line
//response.EnsureSuccessStatusCode(); // Status Code 200-299
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
catch (XunitException e)
{
output.WriteLine(e.InnerException.Message);
}
}
}
About:
public async Task<IActionResult> OnGet()
{
throw new NullReferenceException();
}
Another way is to not use XUnit
, use NUnit
or MSTest
. Take MSTest as an example:
UnitTest1:
[TestClass]
public class UnitTest1
{
private HttpClient _httpClient;
public UnitTest1()
{
var webAppFactory = new WebApplicationFactory<Program>();
_httpClient = webAppFactory.CreateDefaultClient();
}
[TestMethod]
public async Task WeatherForcast()
{
var response = await _httpClient.GetAsync("/WeatherForecast");
var stringResult = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
}
}
Api:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
throw new NullReferenceException();
}
}
答案2
得分: 0
这是.NET 7中的一个错误,在8中已修复。
英文:
This is a bug in .NET 7, fixed in 8.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论