【问题标题】:NSubstitute returns first InlineData value for all testsNSubstitute 返回所有测试的第一个 InlineData 值
【发布时间】:2016-04-28 14:49:46
【问题描述】:

我对测试比较陌生。我们使用 XUnit 和 NSubstitute 作为我们的测试框架,我在应该是一个简单的测试时遇到了麻烦。我正在使用类库与外部 api 交互,我需要能够在执行操作之前确定 api 是否可用。 (我应该提到 dll 已经可以工作了。我们正在追溯添加测试。)

我遇到的问题是,无论测试的 InlineData 是什么,替代品 (client.Execute...) 只返回第一个 InlineData 值的值。如果第一个值是 HttpStatusCode.OK,那么其他 InlineData 值将无法通过测试,因为替换只返回 HttpStatusCode.OK。如果我将 OK 与 Forbidden 交换,那么 HttpStatusCode.OK 将失败,因为替代品只会将 Forbidden 作为 StatusCode 返回。

我可以将它们分解为单独的测试,但我更愿意在这样做之前了解行为。

测试

[Theory]
[InlineData(HttpStatusCode.OK)]
[InlineData(HttpStatusCode.Forbidden)]
[InlineData(HttpStatusCode.BadRequest)]
[InlineData(HttpStatusCode.NotFound)]
public void ConnectionCheck(HttpStatusCode code)
{
    var d2lClient = new d2lClient("userid", "userkey", "mappid", "mappkey", "serviceurl.com", "1");
    var client = Substitute.For<IRestClient>();
    var authenticator = Substitute.For<iITGValenceAuthenticator>();

    client.Execute<WhoAmIUser>(Arg.Any<IRestRequest>()).ReturnsForAnyArgs(x => new RestResponse<WhoAmIUser>()
        {
            StatusCode = code
        });


    d2lClient.GetOrCreateRestClient(client);
    d2lClient.GetOrCreateAuthenticator(authenticator);

    if (code == HttpStatusCode.OK)
    {
        Assert.True(d2lClient.ConnectionCheck(), "client.ConnectionCheck() should be true for " + code);
    }
    else
    {
        Assert.False(d2lClient.ConnectionCheck(), "client.ConnectionCheck() should be false for " + code);
    }
}

方法

public bool ConnectionCheck()
{
    if (_userId == null || _userKey == null || _mAppId == null || _mAppKey == null)
        return false;

    try
    {
        var response = GetRestResponse<WhoAmIUser>(_userId, _userKey, d2lRoute.WhoAmI());

        return response.StatusCode == HttpStatusCode.OK;
    }
    catch (Exception ex)
    {
        return false;
    }
}

public IRestResponse<T> GetRestResponse<T>(string userId, string userKey, string url, List<Parameter> parameters = null, IRestRequest request = null, IRestClient client = null, iITGValenceAuthenticator authenticator = null) where T : new()
{
    /*
       Irrelevant code
    */
    return _client.Execute<T>(request);
}

【问题讨论】:

  • 我认为这里的问题在于 GetRestResponse 的调用方式与预期不同(basic test of the inlinedata works fine)。您可以尝试删除GetRestResponse 中的可选参数并显式传递它们吗?

标签: c# .net unit-testing xunit nsubstitute


【解决方案1】:

感谢 David Tchepak 的帮助!我拿了他的例子并对其进行了更多修改以匹配代码的结构。当我这样做并且它起作用时,很明显我的类库有问题。事实证明,_client 无意中被标记为静态。这无关紧要,直到我们想测试它,我不得不退出客户端创建以允许依赖注入。以前,客户端是每个 api 调用的局部变量。

从 _client 属性中删除静态修饰符后,测试将按预期运行。

改变了

private static IRestClient _client;
private static IRestRequest _request;

private IRestClient _client;
private IRestRequest _request;

在 d2lClient 类中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-19
    相关资源
    最近更新 更多