Untitesting/Moq 方法调用 webrequest
本文关键字:调用 webrequest 方法 Moq Untitesting | 更新日期: 2023-09-27 18:37:01
我想测试一个通过Webrequest发送文本的类,如何使用Moq模拟GetRequest方法来测试GetRequest?
public class Sender
public void Send(string Message)
{
...
WebRequest myReq = GetRequest(sParmeter);
}
protected WebRequest GetRequest(string URl)
{
return WebRequest.Create(URl);
}
}
对于这样的事情,简单的方法是将WebRequest
实例及其操作移动到接口中介后面。
例:
public interface IWebRequestHandler
{
WebRequest GetRequest (string URI);
}
public class WebRequestHandler : IWebRequestHandler
{
public WebRequest GetRequest (string URI)
{
return WebRequest.Create(URl);
}
}
你的发送者类应该有一个可注入的IWebRequestHandler
实例,你可以用MOQ
来模拟它,设置表达式,验证它被调用以及你可能想要的任何其他内容。
public class Sender
{
public IWebRequestHandler Handler{get;set;}
public void Send(string Message)
{
Handler.GetRequest(new URI(Message));//call the method with right params, just an example
}
}
我建议的方法之一与 AD.Net 的响应相同,但是如果您不希望修改现有结构并且仍然进行测试,则可以执行以下操作:
修改原始类,如下所示:
public class Sender
{
public void Send(string Message)
{
...
WebRequest myReq = GetRequest(sParmeter);
}
protected virtual WebRequest GetRequest(string URl)
{
return WebRequest.Create(URl);
}
}
并在测试项目中按如下方式扩展此类:
public class MockSender: Sender
{
private WebRequest _response;
public MockSender(WebRequest response)
{
_response=response; //initialize data to be returned
}
protected override WebRequest GetRequest(string URl)
{
//return your test;
}
}
现在在您的测试中创建一个 MockSender 类型的实例并对其调用 Send 方法。
Moq 希望你的类是抽象的,或者你实现一个接口,从而模拟 AD.Net 描述的接口
希望这有帮助..
另一种方法是将 IWebRequestCreate 方法传递给构造函数。
public HTTPRequestFactory(IWebRequestCreate create)
{
_IWebRequestCreate = create;
}
public HTTPRequestFactory()
{
//Do nothing this is the real constructor, above is just for testing.
}
public WebRequest Create(String uri)
{
Uri _uri = new Uri("http://"+this.address+uri);
request = (HttpWebRequest)this.Create(_uri);
return request;
}
public WebRequest Create(Uri uri)
if (null == _IWebRequestCreate)
{
//use the real one
request = WebRequest.Create(uri);
}
else
{
//testing so use test one
request = _IWebRequestCreate.Create(uri);
}
return request;
}
}然后,您可以使用标准测试来确认它是否像您想要的那样被调用。
[Test]
public void NewwebrequestCreatesWebRequest()
{
var mockCreate = new Mock<IWebRequestCreate>();
mockCreate.Setup(x => x.Create(It.IsAny<Uri>()));
HTTPRequestFactory webrequest = new HTTPRequestFactory(mockCreate.Object);
HttpWebRequest request = (HttpWebRequest)webrequest.Create(testURI);
mockCreate.VerifyAll();
}
[Test]
public void webrequestUsesAddressProperty()
{
var mockCreate = new Mock<IWebRequestCreate>();
string IP = "10.99.99.99";
Uri expected = new Uri("http://10.99.99.99/services");
mockCreate.Setup(x => x.Create(expected));
HTTPRequestFactory webrequest = new HTTPRequestFactory(mockCreate.Object);
webrequest.address = IP;
HttpWebRequest request = (HttpWebRequest)webrequest.Create(testURI);
mockCreate.VerifyAll();
}
两个 Create 函数的原因是你想要传入一个字符串 Create(string),而 IWebRequestCreate 需要一个 Create(Uri)。
已编辑,因为标准依赖项注入不适用于 IWebRequestCreate。 标准模式是使用接口实例化对象并通过构造函数传递它。 由于 WebRequest 不能使用构造函数创建,并且接口不能实例化,因此上述逻辑可以解决此问题。