模拟库方法
Mocking Library Method
我最近开始tdd,但是我的模拟知识不完整。我知道基础知识,但是,测试一些没有考虑 tdd 而编写的方法,真的让我很困惑。
这是我要测试的内容
public int GetThirdPartyUserId(int serviceTypeId, string accessToken)
{
ThirdPartyRequestDetail requestDetail = GetThirdPartyRequestDetails(serviceType, accessToken);
IHttwrapConfiguration configuration = new HttwrapConfiguration(requestDetail.BaseUrl);
IHttwrapClient httwrap = new HttwrapClient(configuration);
Task<IHttwrapResponse<OpenAuthUserResponse>> response = httwrap.GetAsync<OpenAuthUserResponse>(requestDetail.PathAndQuery);
try
{
if (response.Result.Data != null && response.Status != TaskStatus.Faulted)
{
//Do something
}
else
{
//WANT TO TEST HERE
}
}
}
这是我的测试方法
private Mock<IHttwrapClient> _httpwrap;
public void httprwapTest()
{
string accessToken = "invalid";
int thirdPartySiteId = (int)ThirdPartyServiceType.GooglePlus;
string requestPath = _fixture.Create<string>();
_httpwrap.Setup(item => item.GetAsync(requestPath)).Returns(Task.FromResult(new HttwrapResponse(HttpStatusCode.BadRequest, "body")));
OpenAuthUserResponse response = _oauthAuthenticator.GetThirdPartyUser(thirdPartySiteId, accessToken);
Assert.AreEqual(response.Error, OauthAuthenticatorErrorType.RequestFaulted);
}
下面是我尝试做的,但没有被触发。
_httpwrap.Setup(item => item.GetAsync(requestPath)).Returns(Task.FromResult(new HttwrapResponse(HttpStatusCode.BadRequest, "body")));
当 httpwrap 给我一个 badrequest 响应代码时,我如何测试我的 类 行为?
在当前形式下,您无法使用传统的模拟框架来帮助您进行测试。为了让模拟工作,您必须 Setup
与您在生产代码中使用的模拟相同。目前,您在测试中创建的模拟与您的测试方法所依赖的 IHttpwrapClient
之间没有任何联系。
您需要做的第一步是将 HttpwrapClient
的创建移到您要测试的方法之外。然后,您需要通过它的接口使其对代码可用,以便您稍后可以从测试中提供它。
提供接口的常用方法有 3 种。
- 将它注入到你的 class
的构造函数中
- 通过 属性 将其注入您的 class
- 将其作为参数传递给函数
通常,构造函数注入优于 属性 注入,但这在很大程度上取决于您哪种方法最有效(它们各有优点和缺点)以及哪种方法对您的数据最有意义重新注射。
然后您将创建界面的 Mock 并将其适当地注入到您的代码中。
就生产代码而言,您仍然需要创建具体实例 class。您可以在调用 class 时直接执行此操作,也可以通过工厂之类的方式执行此操作,也可以使用 IoC 容器,例如 Castle Winsor 或 Ninject(还有其他几个)。
我最近开始tdd,但是我的模拟知识不完整。我知道基础知识,但是,测试一些没有考虑 tdd 而编写的方法,真的让我很困惑。
这是我要测试的内容
public int GetThirdPartyUserId(int serviceTypeId, string accessToken)
{
ThirdPartyRequestDetail requestDetail = GetThirdPartyRequestDetails(serviceType, accessToken);
IHttwrapConfiguration configuration = new HttwrapConfiguration(requestDetail.BaseUrl);
IHttwrapClient httwrap = new HttwrapClient(configuration);
Task<IHttwrapResponse<OpenAuthUserResponse>> response = httwrap.GetAsync<OpenAuthUserResponse>(requestDetail.PathAndQuery);
try
{
if (response.Result.Data != null && response.Status != TaskStatus.Faulted)
{
//Do something
}
else
{
//WANT TO TEST HERE
}
}
}
这是我的测试方法
private Mock<IHttwrapClient> _httpwrap;
public void httprwapTest()
{
string accessToken = "invalid";
int thirdPartySiteId = (int)ThirdPartyServiceType.GooglePlus;
string requestPath = _fixture.Create<string>();
_httpwrap.Setup(item => item.GetAsync(requestPath)).Returns(Task.FromResult(new HttwrapResponse(HttpStatusCode.BadRequest, "body")));
OpenAuthUserResponse response = _oauthAuthenticator.GetThirdPartyUser(thirdPartySiteId, accessToken);
Assert.AreEqual(response.Error, OauthAuthenticatorErrorType.RequestFaulted);
}
下面是我尝试做的,但没有被触发。
_httpwrap.Setup(item => item.GetAsync(requestPath)).Returns(Task.FromResult(new HttwrapResponse(HttpStatusCode.BadRequest, "body")));
当 httpwrap 给我一个 badrequest 响应代码时,我如何测试我的 类 行为?
在当前形式下,您无法使用传统的模拟框架来帮助您进行测试。为了让模拟工作,您必须 Setup
与您在生产代码中使用的模拟相同。目前,您在测试中创建的模拟与您的测试方法所依赖的 IHttpwrapClient
之间没有任何联系。
您需要做的第一步是将 HttpwrapClient
的创建移到您要测试的方法之外。然后,您需要通过它的接口使其对代码可用,以便您稍后可以从测试中提供它。
提供接口的常用方法有 3 种。
- 将它注入到你的 class 的构造函数中
- 通过 属性 将其注入您的 class
- 将其作为参数传递给函数
通常,构造函数注入优于 属性 注入,但这在很大程度上取决于您哪种方法最有效(它们各有优点和缺点)以及哪种方法对您的数据最有意义重新注射。
然后您将创建界面的 Mock 并将其适当地注入到您的代码中。
就生产代码而言,您仍然需要创建具体实例 class。您可以在调用 class 时直接执行此操作,也可以通过工厂之类的方式执行此操作,也可以使用 IoC 容器,例如 Castle Winsor 或 Ninject(还有其他几个)。