NSubstitute returns 所有测试的第一个 InlineData 值
NSubstitute returns first InlineData value for all tests
我对测试比较陌生。我们使用 XUnit 和 NSubstitute 作为我们的测试框架,我在进行简单测试时遇到了麻烦。我正在使用 Class 库与外部 api 交互,我需要能够在执行操作之前确定 api 是否可用。 (我应该提到 dll 已经可以工作了。我们正在追溯添加测试。)
我遇到的问题是,无论用于测试的 InlineData 是什么,替代 (client.Execute...) 都只会 returns 第一个 InlineData 值的值。如果第一个值是 HttpStatusCode.OK,则其他 InlineData 值无法通过测试,因为仅替代 returns HttpStatusCode.OK。如果我将 OK 与 Forbidden 交换,那么 HttpStatusCode.OK 会失败,因为替代品只会 returns 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);
}
感谢 David Tchepak 的帮助!我拿他的例子做了一些修改以匹配代码的结构。当我这样做并且它起作用时,很明显我的 class 库出了点问题。事实证明,_client 无意中被标记为静态。这并不重要,直到我们想要测试它并且我不得不退出客户端创建以允许依赖注入。以前,客户端是每个 api 调用的局部变量。
从 _client 属性 中删除静态修饰符后,测试按预期运行。
已更改
private static IRestClient _client;
private static IRestRequest _request;
至
private IRestClient _client;
private IRestRequest _request;
在 d2lClient class.
我对测试比较陌生。我们使用 XUnit 和 NSubstitute 作为我们的测试框架,我在进行简单测试时遇到了麻烦。我正在使用 Class 库与外部 api 交互,我需要能够在执行操作之前确定 api 是否可用。 (我应该提到 dll 已经可以工作了。我们正在追溯添加测试。)
我遇到的问题是,无论用于测试的 InlineData 是什么,替代 (client.Execute...) 都只会 returns 第一个 InlineData 值的值。如果第一个值是 HttpStatusCode.OK,则其他 InlineData 值无法通过测试,因为仅替代 returns HttpStatusCode.OK。如果我将 OK 与 Forbidden 交换,那么 HttpStatusCode.OK 会失败,因为替代品只会 returns 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);
}
感谢 David Tchepak 的帮助!我拿他的例子做了一些修改以匹配代码的结构。当我这样做并且它起作用时,很明显我的 class 库出了点问题。事实证明,_client 无意中被标记为静态。这并不重要,直到我们想要测试它并且我不得不退出客户端创建以允许依赖注入。以前,客户端是每个 api 调用的局部变量。
从 _client 属性 中删除静态修饰符后,测试按预期运行。
已更改
private static IRestClient _client;
private static IRestRequest _request;
至
private IRestClient _client;
private IRestRequest _request;
在 d2lClient class.