C# 使用Nsubstitute模拟RestClient executesync
使用Nsubstitute从RestSharp模拟RestClient的ExecuteAsync方法一直很困难。我在这里看到了一个使用Moq的示例:但我始终无法理解以下代码使用nsubstitute失败的原因:C# 使用Nsubstitute模拟RestClient executesync,c#,unit-testing,restsharp,nsubstitute,C#,Unit Testing,Restsharp,Nsubstitute,使用Nsubstitute从RestSharp模拟RestClient的ExecuteAsync方法一直很困难。我在这里看到了一个使用Moq的示例:但我始终无法理解以下代码使用nsubstitute失败的原因: RestClientMock.When(x => x.ExecuteAsync(Arg.Any<IRestRequest>(), Arg.Any<Action<IRestResponse>>())) .Do(x =&g
RestClientMock.When(x => x.ExecuteAsync(Arg.Any<IRestRequest>(), Arg.Any<Action<IRestResponse>>()))
.Do(x => new RestResponse { StatusCode = HttpStatusCode.NotFound });
我就是这样设置的,然后它会像这样命中要测试的代码:
var tcs = new TaskCompletionSource<SendEmailResponse>();
_restClient.ExecuteAsync(_restRequest, (restResponse) => {
if (restResponse.StatusCode != HttpStatusCode.OK)
tcs.SetResult(new SendEmailResponse(ResponseType.Error, restResponse));
else if (!_enableEmails)
tcs.SetResult(new SendEmailResponse(ResponseType.EmailsTurnedOff, restResponse));
else
tcs.SetResult(new SendEmailResponse(ResponseType.Sent, restResponse));
});
return tcs.Task;
它似乎从未在模拟中执行回调代码,只是挂起,因为tcs从未设置。这里有人知道怎么做吗
编辑:已解决。谢谢恩科西。所以我只是像下面解释的那样更新它,没有回来。如果我仔细阅读文档,我会看到David Tchepak在评论中提到的部分。ExecuteAsync的函数签名是:
之后,您应该能够模拟函数ExecuteTaskAsync。ExecuteAAsync的函数签名是:
在这之后,您应该能够模拟函数ExecuteTaskAsync。通过初始检查,您似乎没有对传入模拟方法的回调操作进行任何操作
RestClientMock
.ExecuteAsync(
Arg.Any<IRestRequest>(),
Arg.Do<Action<IRestResponse, RestRequestAsyncHandle>>(callback =>
callback(new RestResponse { StatusCode = HttpStatusCode.NotFound}, null))
)
从最初的检查来看,您似乎没有对传入模拟方法的回调操作做任何事情
RestClientMock
.ExecuteAsync(
Arg.Any<IRestRequest>(),
Arg.Do<Action<IRestResponse, RestRequestAsyncHandle>>(callback =>
callback(new RestResponse { StatusCode = HttpStatusCode.NotFound}, null))
)
从最初的检查来看,您似乎没有对传入模拟方法的回调操作执行任何操作。在.do调用中,您正在新建一个Response,但它没有在任何地方使用,因此将被忽略。根据@Nkosi的回答,您需要将该响应传递给回调。另请参见:,从初始检查来看,您似乎没有对传入模拟方法的回调操作执行任何操作。在.do调用中,您正在新建一个Response,但它没有在任何地方使用,因此将被忽略。根据@Nkosi的回答,您需要将该响应传递给回调。另请参见:,我使用的ExecuteAsync来自RestClientExtensions,定义为:public static restrequestAsynchHandle ExecuteAsynct此IRestClient客户端、IRestRequest请求、操作回调;我不确定是否可以在Moq中模拟扩展方法?不可能在Moq中模拟扩展方法你们都是对的。扩展方法不能在nsub中模拟。我将签名改为包含Restrequestasynchandle,它开始点击模拟,但正如Nkosi之前提到的,它所做的只是更新响应。在进一步阅读文档和上面的注释后,我能够解决问题。@Newbie:鉴于您希望公开基于任务的API,我建议使用RestClient的基于任务的API,而不是基于回调的API。我使用的ExecuteAsync来自RestClientExtensions,定义为:公共静态RestRequestAsynchHandle ExecuteAsync此IRestClient客户端、IRestRequest请求、动作回调;我不确定是否可以在Moq中模拟扩展方法?不可能在Moq中模拟扩展方法你们都是对的。扩展方法不能在nsub中模拟。我将签名改为包含Restrequestasynchandle,它开始点击模拟,但正如Nkosi之前提到的,它所做的只是更新响应。在进一步阅读文档和上面的注释后,我能够解决问题。@Newbie:鉴于您希望公开基于任务的API,我建议使用RestClient的基于任务的API,而不是基于回调的API。
var restResponse = await _restClient.ExecuteTaskAsync(_restRequest);
if (restResponse.StatusCode != HttpStatusCode.OK)
return new SendEmailResponse(ResponseType.Error, restResponse);
else if (!_enableEmails)
return new SendEmailResponse(ResponseType.EmailsTurnedOff, restResponse);
else
return new SendEmailResponse(ResponseType.Sent, restResponse);
RestClientMock
.ExecuteAsync(
Arg.Any<IRestRequest>(),
Arg.Do<Action<IRestResponse, RestRequestAsyncHandle>>(callback =>
callback(new RestResponse { StatusCode = HttpStatusCode.NotFound}, null))
)