gpt4 book ai didi

c# - 使用 Moq 将参数修改为 stub void 方法

转载 作者:行者123 更新时间:2023-11-30 17:13:55 25 4
gpt4 key购买 nike

我遇到了一场完美 Storm ,阻止我测试类(class)。该类是一个 RestClient,它包装了一个内部 HttpClient(我无法修改)。 HttpClient 上的 ExecuteMethod 方法无效。它接受 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 操作被执行时,我观察到两件事,这两件事都是我所期望的:

  1. 传入的 IHttpMethod (m) 具有我期望的属性。
  2. 将模拟对象分配给 m 后,它包含我在测试中设置的 stub 值。

但是,在执行回调并将控制返回到我的应用程序代码后,我的 method 变量仍然具有我在上面的步骤 1 中看到的旧值,这会在尝试时导致空引用异常阅读 method.ResponseBodyAsStream

我正在尝试做的事情是否可以实现?如果是这样,如何?谢谢!

最佳答案

我已经通过 vis mocking 复制了您的设置,但没有发现任何问题:

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() 扩展方法(我假设这是一个扩展方法,因为智能感知没有在 MemoryStream 上向我显示它)。你的问题可能在那里吗?

顺便说一句,您尝试做的事情几乎肯定可以通过最小起订量实现。

关于c# - 使用 Moq 将参数修改为 stub void 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9281708/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com