NSubstitute不替代方法

时间:2015-07-01 13:07:02

标签: c# nsubstitute

我有我的测试目标类:

public class ApiClient
{

    private IRestClient authz_rest_client;
    private IRestClient api_rest_client;


    // Injection feature for testing
    internal ApiClient(IRestClient authz_rest_client, IRestClient api_rest_client)
    {
        this.authz_rest_client = authz_rest_client;
        this.api_rest_client = api_rest_client;
    }
    //...

所以,我按如下方式注入我的替换RestSharp客户端:

[TestFixture]
class AuthzApiClientTests
{

    private ApiClient api_client;

    private IRestClient authz_rest_client;
    private IRestClient api_rest_client;

    private IRestRequest request;
    private IRestResponse<OAuth2AuthzCodeResponse> response;

    [SetUp]
    public void SetUp()
    {
        this.authz_rest_client = NSubstitute.Substitute.For<IRestClient>();
        this.api_rest_client = NSubstitute.Substitute.For<IRestClient>();

        this.request = NSubstitute.Substitute.For<IRestRequest>();
        this.response = NSubstitute.Substitute.For<IRestResponse<OAuth2AuthzCodeResponse>>();

        this.authz_rest_client.Execute<OAuth2AuthzCodeResponse>(request).Returns(response);

        this.api_client = new ApiClient(this.authz_rest_client, this.api_rest_client);
        this.api_client.configure(
            "client_id",
            "user",
            "passwd"
        );
    }

然后,我写了一个测试:

    [Test]
    public void Should_ReturnCorrectRequestTokenServiceEndpoint()
    {

        response.StatusCode = HttpStatusCode.Unauthorized;
        response.Data = new OAuth2AuthzCodeResponse()
        {
            Error = StringEnum.GetStringValue(OAuth2ErrorTypes.invalid_client)  //CLIENT IS NOT REGISTERED ON LEST SYSTEM.
        };

        this.api_client.Invoking(c => c.GrantAuthorization())
            .ShouldThrow<OAuth2APIException>();
    }

如您所见,我想测试GrantAuthorization课程的ApiClient方法。这种方法是:

IRestRequest authzcode_request = new AuthzCodeRequest(
            this.settings.AuthzAuthorizeEndpoint,
            this.settings.ClientId,
            this.settings.ClientSecret,
            this.settings.User,
            this.settings.Password
        );

        IRestResponse<OAuth2AuthzCodeResponse> authzcode_response = this.authz_rest_client.Execute<OAuth2AuthzCodeResponse>(authzcode_request);
        this.check_response(authzcode_response);

        this.settings.AuthzCode = authzcode_response.Data.Code;
        this.settings.AuthzCodeExpirationThreshold = DateTime.Now.AddSeconds(authzcode_response.Data.Expires_in);

我的测试目标是“捕获”我的Execute<OAuth2AuthzCodeResponse>方法,以便返回我的替换回复。

问题在于,当我执行测试并停在此行时,结果不是我之前设置的响应。

2 个答案:

答案 0 :(得分:1)

我在完整的示例中遇到了问题,但我确实注意到SetUp正在使用的内容:

request = Substitute.For<IRestRequest>();
response = Substitute.For<IRestResponse<OAuth2AuthzCodeResponse>>();
authz_rest_client.Execute<OAuth2AuthzCodeResponse>(request).Returns(response);

此处的第三行表示,只要authz_rest_client.Execute<OAuth2AuthzCodeResponse>()实例调用request,它就会返回response。但request似乎永远不会在代码中的任何位置使用,因此Execute永远不会实际返回response

对于response的任何调用,以下行都会返回Execute<OAuth2AuthzCodeResponse>()

authz_rest_client.Execute<OAuth2AuthzCodeResponse>(null).ReturnsForAnyArgs(response);

但我不确定你想要的是什么?相反,您可能希望在收到AuthzCodeRequest类型的请求时存根单个调用,例如特定响应。

答案 1 :(得分:0)

解决!

我尝试使用它:

this.authz_rest_client.Execute<OAuth2AuthzCodeResponse>(Arg.Any<IRestRequest>()).Returns(response);

此解决方案类似于以前的答案方法。

但是,我不明白为什么不能正常工作......