对使用代理的Webrequest进行单元测试 [英] Unit test a webrequest that uses a proxy
问题描述
我正在编写一个通过代理从Web上获取一些数据的应用程序.作为核心功能,我使用 simple-http-此站点上的代理类. (如下所示)
由于我的应用仅以某种方式运行,因此我不知道一切是否按照我的意愿进行,因此我研究了网络,并进行了单元测试.我已经实施了许多测试,但绝对不知道如何测试需要从外部来源输入的内容.
我在网上找到了一些解决方案,但没有解决方案,那就是测试代理"连接.
实际上,我不想测试此课程,但是我希望有人对此提供帮助,因此可以理解它的工作原理.
问候
Delicious_cake
简单的http类:
hi there,
i''m writing an application that is getting some data from the web over a proxy. as core function i use the simple-http-proxy-class from this site. (can be seen below)
as my app is runnning only somehow and i don''t know if everything is going as i want it to, i researched the web and i came accross unit testing. i already implemented many tests, but have absolutly no idea how to test something that would need imput from an external source.
i found some solutions on the web, but there''s no solution, that is testing a "proxified" connection.
actually i don''t want to test this class, but i want somebody to help me with this, so is understand how it would work.
greetings
delicious_cake
the simple http class:
class simplehttp
{
public string geturl(string url, string proxyip, int port, string proxylogin, string proxypassword)
{
HttpWebResponse resp;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.UserAgent = "Mozilla/5.0";
req.AllowAutoRedirect = true;
req.ReadWriteTimeout = 5000;
req.CookieContainer = new CookieContainer();
req.Referer = "";
req.Headers.Set("Accept-Language", "en,en-us");
StreamReader stream_in;
WebProxy proxy = new WebProxy(proxyip, port);
//if proxylogin is an empty string then don't use proxy credentials (open proxy)
if (proxylogin != "") proxy.Credentials = new NetworkCredential(proxylogin, proxypassword);
req.Proxy = proxy;
string response = "";
try
{
resp = (HttpWebResponse)req.GetResponse();
stream_in = new StreamReader(resp.GetResponseStream());
response = stream_in.ReadToEnd();
stream_in.Close();
}
catch (Exception ex)
{
}
return response;
}
}
PS:
我已经尝试制作一个本地代理和一个本地Web服务器,并执行诸如集成测试之类的事情.
它的工作原理,如果:
1.代理正确且网址正确->表现得像人所见
2.代理正确,网址不正确->表现符合预期
3.代理不正确,网址正确->表现不符合预期.即使该功能应使用的端口不是本地代理,该功能也会返回url内容
我不知道为什么该函数会使用此设置返回url内容.
PS:
i already tried to make a local proxy and a local webserver and perfom something like an integration test.
its working, if the:
1. proxy is correct and url is correct --> behaves as ecpected
2. proxy is correct and url is incorrect --> behaves as expected
3. proxy is incorrect and url is correct --> don''t behaves as expected. the url content is returned by the function even if the port thats should be used by the function is no local proxy
i have no idea, why the function returns the url content with this setup.
推荐答案
代理通常具有与您要使用的服务不同的端口. br/>
以下是您应该考虑的一些改进:
* SimpleHttp在面向对象的方式中不是真正的类".您仅具有一个包含方法的类.更好:提供一个看起来像这样的IStringDataProvider接口:
The proxy typically has a different port than the service you are trying to consume.
Here are some improvements you should consider:
* SimpleHttp is no real "class" in object-orientated manner. You have simply a class that contains a method. Better: Provide an IStringDataProvider Interface which could look like:
public interface IStringDataProvider
{
string GetContent();
}
然后,您可以从http以外的其他来源获取内容,并且可以用模拟提供程序替换它,因此测试将更加容易.可以使用依赖项注入将URL传递到http-provider-instance(请参见下面的代码).
* GetUrl听起来像嘿,给我URL!".更好:GetContent或GetContentByUrl
*不要在每个请求上传递所有代理属性.更好:在应用程序启动时设置WebRequest.DefaultWebProxy
.然后,您将独立于是否使用代理,并且整个应用程序将使用相同的代理.
*不要吞下异常!您有一个TryGetContent-Method返回操作是否成功,或者您要检查是否发生错误时处理异常-通常在GUI中完成.
放在一起:
Then you are able to get the content from other sources than http - and your testing will be easier as you can replace it with a mock-provider. The url can be passed to the http-provider-instance with dependency injection (see code below).
* GetUrl sounds like "Hey, get me the url!". Better: GetContent or GetContentByUrl
* Dont pass all the proxy-propertys on each request. Better: Set the WebRequest.DefaultWebProxy
at application startup. Then you are independent of using a proxy or not and your whole application will use the same proxy.
* Dont swallow exceptions! Either you have a TryGetContent-Method returning whether the operation succeeded or you handle the exception when you want to check whether an error occured - this is typically done in the GUI.
Putting all together:
interface IStringDataProvider
{
string GetContent();
}
class HttpStringDataProvider : IStringDataProvider
{
public HttpStringDataProvider(string url) //The url is passed with dependency injection i.e. through parameters on construction
{
Url = url;
}
public string Url { get; private set; }
private CookieContainer cookies = new CookieContainer();
public string GetContent()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.UserAgent = "Mozilla/5.0";
request.AllowAutoRedirect = true;
request.ReadWriteTimeout = 5000;
request.CookieContainer = cookies;
request.Referer = "";
request.Headers.Set("Accept-Language", "en,en-us");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
return streamReader.ReadToEnd();
}
}
启动时:
On startup:
if (proxyType == "http")
{
WebProxy proxy = new WebProxy(myProxyHost, myProxyPort);
proxy.Credentials = new NetworkCredential(myProxyUsername, myProxyPassword);
WebRequest.DefaultWebProxy = proxy; //This proxy will be used by all HttpWebRequests if their Proxy-Property is not set.
}
else if (proxyType == "system")
{
WebRequest.DefaultWebProxy = WebRequest.GetSystemWebProxy(); //Settings from Internet Explorer (default)
}
else if (proxyType == "no")
{
WebRequest.DefaultWebProxy = null; //This will speed up the whole a lot, because the default is the proxy used by IE and otherwise the .Net-Framework tries to gather the IE-proxy settings on each request which is very slow
}
这篇关于对使用代理的Webrequest进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!