测试由 Refit 实现的 API 时出现 NullReferenceException

NullReferenceException when testing API implemented by Refit

我正在尝试使用 Refit 测试一些错误响应(BadRequest、Unauthorized ...),因此我实现了一个 TestHandler returns 任何所需的响应。响应在“OK”(HTTP 状态代码 200)响应下工作正常:

public class Program
{
    private static async Task Main()
    {
        var api = RestService.For<ITest>(
            new HttpClient(new TestHandler(HttpStatusCode.OK))
                {
                    BaseAddress = new Uri("https://example.com")
                }
            );
        Console.WriteLine(await api.Test("foo").ConfigureAwait(false));
    }
}

public interface ITest
{
    [Get("/foo/{bar}")]
    Task<string> Test(string bar);
}

public class TestHandler : HttpMessageHandler
{
    private readonly HttpResponseMessage _response;

    public TestHandler(HttpStatusCode httpStatusCode)
        => _response = new HttpResponseMessage(httpStatusCode) { Content = new StringContent("Yay!") };

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        => Task.FromResult(_response);
}

但是,每当我将响应状态代码更改为例如 BadRequest (400)、NotFound (404) 或 Unauthorized (401) 时,Refit 都会抛出 NullReferenceException:

Object reference not set to an instance of an object.
   at Refit.DefaultApiExceptionFactory.<CreateExceptionAsync>d__4.MoveNext() in /_/Refit/RefitSettings.cs:line 183
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Refit.RequestBuilderImplementation.<>c__DisplayClass14_0`2.<<BuildCancellableTaskFuncForMethod>b__0>d.MoveNext() in /_/Refit/RequestBuilderImplementation.cs:line 313
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at RefitTest.Program.<Main>d__0.MoveNext() in C:\Users\Rob\Source\Repos\RefitTest\RefitTest\Program.cs:line 18

这指向RefitSettings.cs line 183。但我不明白为什么 200 OK 会起作用而其他任何反应都不起作用?我做错了什么?

编辑:为了进一步调试,我克隆了 Refit 并将 Refit NuGet 包交换为对 Refit 项目的项目引用。这导致 InvalidOperationException: ITest doesn't look like a Refit interface. Make sure it has at least one method with a Refit HTTP method attribute and Refit is installed in the project。另外,退回几个版本(我已经转到 5.2.4)也无济于事。

在同事的帮助下找到了!原来 HttpResponseMessage 需要 some/any RequestMessage.

改变

public TestHandler(HttpStatusCode httpStatusCode)
    => _response = new HttpResponseMessage(httpStatusCode)
    { 
        Content = new StringContent("Yay!") 
    };

收件人:

public TestHandler(HttpStatusCode httpStatusCode)
    => _response = new HttpResponseMessage(httpStatusCode)
    {
        RequestMessage = new(),  // <-- This one here...
        Content = new StringContent("Yay!")
    };

它按预期工作。正如在问题(和评论)中,我很接近,但显然是半睡半醒,因为它正是它指向我的地方。

我已提交问题 here