使用NSubstitute模拟IFlurl库方法会引发空引用异常

时间:2018-11-29 21:57:46

标签: c# mocking xunit nsubstitute flurl

我正在使用flurl,并且尝试对以下代码进行单元测试:

public class MyRestClient
{
    public async Task<T> Request<T>(IFlurlRequest flurlRequest)
    {
        try  
        {
            return await flurlRequest
                    .WithOAuthBearerToken("my-hardcoded-token")
                    .GetAsync()
                    .ReceiveJson<T>();  
        }
        catch(HttpFlurlException)
        {
            throw new MyCustomException();
        }
    }
}

我要测试的是,如果flurlRequest抛出类型为HttpFlurlException的异常,那么它将抛出MyCustomException。我的想法是起订flurlrequest并引发异常。这是我布置测试的方式:

var moq = Substitute.For<IFlurlRequest>();
// Problem is with line below:
moq.When(x => x.WithOAuthBearerToken("dummy")).Do(x => { throw new HttpFlurlException(); } );

var myClient = new MyRestClient();

Func<Task> call = async () => { await myClient.Request<object>(moq); };

// FluentAssertions
call.Should().Throw<MyCustomException>();

运行时的代码返回NullReferenceException:

Exception has occurred: CLR/System.NullReferenceException
An exception of type 'System.NullReferenceException' occurred in 
Flurl.Http.dll but was not handled in user code: 'Object reference not 
set to an instance of an object.'
at Flurl.Http.HeaderExtensions.WithHeader[T](T clientOrRequest, String name, Object value)

所以我看到了它与标题相关的内容...所以我尝试通过添加以下内容来模拟它:

var moq = Substitute.For<IFlurlRequest>();
moq.Headers.Returns(new Dictionary<string, object> { {"dummy", new {} };

但是我不断遇到同样的异常。我究竟做错了什么?

1 个答案:

答案 0 :(得分:1)

WithOAuthBearerToken是扩展方法,这意味着NSubstitute无法直接对其进行模拟。在扩展方法上调用textWhen..Do时,它将运行扩展方法的实际代码。 (我建议将NSubstitute.Analyzers添加到测试项目中以检测这些情况。)

在撰写本文时,通过扩展方法实现,应该有可能模拟Returns属性以引发所需的异常,但是我认为这会拖累过多的库内部知识,并且会导致脆性测试与该特定实现紧密结合(这是我们旨在通过模拟避免的事情!)。

如我在this answer中概述的那样,我会非常谨慎地以这种方式模拟第三方库:

  

另一个选择是在不同级别进行测试。我认为测试当前代码的摩擦在于,我们试图替代[第三方库]的详细信息,而不是为分区应用程序的逻辑详细信息而创建的接口。搜索“不要嘲笑您不拥有的类型”,以获取更多有关这可能导致问题的原因的信息(我在here之前就已经对此进行过介绍)。

如果可能的话,我建议尝试改用Flurl's built-in testing support。这样一来,您就可以伪装所需的行为,而无需有关Flurl内部实现的特定详细信息。

相关问题