我有一场完美的风暴让我无法测试课程。该类是RestClient
包裹内部HttpClient
(我无法修改)。 ExecuteMethod
上的HttpClient
方法无效。它接受IHttpMethod
,并根据服务器的响应修改此对象。我想嘲笑ExecuteMethod
,以便它为我修改IHttpMethod
。我正在尝试使用Callback
来实现这一点,但它无效。
以下是发送请求的代码:
var httpClient = this.httpClientFactory.CreateHttpClient();
httpClient.ExecuteMethod(method);
var response = this.GetResourceResponse<T>(method.ResponseBodyAsStream.AsString());
response.ResponseHeaders = method.ResponseHeaders;
response.Status = method.StatusCode.ToString();
response.StatusCode = (int)method.StatusCode;
return response;
这是我嘲笑的尝试:
var mockHttpMethod = new Mock<IHttpMethod>();
mockHttpMethod.Setup(m => m.ResponseBodyAsStream).Returns(new MemoryStream(Encoding.UTF8.GetBytes("foo")));
var modifyHttpMethod = new Action<IHttpMethod>(m =>
{
m = mockHttpMethod.Object;
});
var mockHttpClient = new Mock<IHttpClient>();
mockHttpClient.Setup(c => c.ExecuteMethod(It.IsAny<IHttpMethod>()))
.Callback<IHttpMethod>(modifyHttpMethod);
var mockHttpClientFactory = new Mock<ILegalHoldHttpClientFactory>();
mockHttpClientFactory.Setup(f => f.CreateHttpClient()).Returns(mockHttpClient.Object);
var restClient = new RestClient(mockHttpClientFactory.Object);
当执行modifyHttpMethod
动作时,我会观察到两件事,我期望这两件事:
IHttpMethod
(m
)具有我希望它拥有的属性。m
后,它包含我在测试中设置的存根值。但是,在执行回调并将控制权返回给我的应用程序代码之后,我的method
变量仍然具有我在上面的步骤1中看到的旧值,这会在尝试读取{时导致空引用异常{1}}。
我正在尝试做甚至可以实现的目标?如果是这样,怎么样?谢谢!
答案 0 :(得分:2)
我已经将你的设置复制到了模拟中,并且找不到任何问题:
public interface IHttpMethod
{
MemoryStream ResponseBodyAsStream { get; set; }
}
public interface IHttpClient
{
void ExecuteMethod(IHttpMethod method);
}
public class HttpClient : IHttpClient
{
#region IHttpClient Members
public void ExecuteMethod(IHttpMethod method)
{
}
#endregion
}
public class Factory
{
public virtual IHttpClient CreateHttpClient()
{
return new HttpClient();
}
}
public class ClassUnderTest
{
private readonly Factory _factory;
public ClassUnderTest(Factory factory)
{
_factory = factory;
}
public string GetResponseAsString(IHttpMethod method)
{
var myClient = _factory.CreateHttpClient();
myClient.ExecuteMethod(method);
return method.ResponseBodyAsStream.ToString();
}
}
[TestClass]
public class ScratchPadTest
{
[TestMethod]
public void SampleTest()
{
var mockHttpMethod = new Mock<IHttpMethod>();
mockHttpMethod.Setup(x => x.ResponseBodyAsStream).Returns(new MemoryStream(Encoding.UTF8.GetBytes("foo")));
var modifyHttpMethod = new Action<IHttpMethod>(m =>
{
m = mockHttpMethod.Object;
});
var mockHttpClient = new Mock<IHttpClient>();
mockHttpClient.Setup(c => c.ExecuteMethod(It.IsAny<IHttpMethod>())).Callback<IHttpMethod>(modifyHttpMethod);
var myFactoryStub = new Mock<Factory>();
myFactoryStub.Setup(f => f.CreateHttpClient()).Returns(mockHttpClient.Object);
var myCut = new ClassUnderTest(myFactoryStub.Object);
Assert.IsNotNull(myCut.GetResponseAsString(mockHttpMethod.Object));
}
}
该测试通过,意味着内存流不为空(否则将生成异常)。我能看到的唯一X因子是你的AsString()扩展方法(我假设这是一个扩展方法,因为intellisense没有在MemoryStream上向我展示)。你的问题可以在那里吗?
顺便说一句,你想要做的事几乎可以用Moq实现。