[英]How to Unit Test method that uses a Webservice on Windows Phone?
I'm working on a project that retrieves information from an external webservice API, but I'm not sure how I'm supposed to test it, I'm quite new at Testing and I have done just a couple of Unit Test, but as far as I know I have to mock the webservice functionality, I've been looking for info regarding this subject but haven't found anything for Windows Phone yet. 我正在一个项目中,该项目从外部Web服务API检索信息,但是我不确定如何测试它,我在Testing中是一个新手,并且只做了几次单元测试,但是据我所知我必须模拟Web服务功能,我一直在寻找有关此主题的信息,但尚未为Windows Phone找到任何东西。 What's the standard procedure for these type of cases? 这些案件的标准程序是什么?
Here's a simple version of what I want to test: 这是我要测试的简单版本:
public async Task<List<Song>> FetchSongsAsync(String query)
{
if (String.IsNullOrEmpty(query))
return null;
string requestUrl = "webservice url";
var client = new HttpClient();
var result = await client.GetStringAsync(new Uri(requestUrl,UriKind.Absolute));
try
{
var result = JsonConvert.DeserializeObject<RootObject>(result);
return result;
}
catch (Exception)
{
return null;
}
}
Thanks! 谢谢!
Decouple your code from its dependencies: make content loading and its deserialization replaceable : 分离从它的依赖您的代码:使内容加载和反序列化的更换 :
private readonly IClient client;
private readonly ISerializer serializer;
public YourService(IClient client, ISerializer serializer)
{
_client = client;
_serializer = serializer;
}
public async Task<List<Song>> FetchSongsAsync(String query)
{
try
{
var result = await _client.GetStringAsync(new Uri("http://example.com"));
return _serializer.DeserializeObject<RootObject>(result);
}
catch (Exception)
{
return null;
}
}
The first thing that may help is understand and use dependency injection. 可能有帮助的第一件事是了解并使用依赖项注入。 Basically taking any dependencies of your object/method/etc and (as it states) injecting them into the object/method/etc. 基本上获取对象/方法/等的任何依赖关系,并将其注入到对象/方法/等中。 For example, you are having a difficult time figuring out how to test the method because the method depends on being able to access the web service. 例如,您很难确定如何测试该方法,因为该方法取决于能否访问Web服务。 There are a couple things you can do after this. 此后您可以做几件事。
One thing to do is to check out mocking frameworks such as Moq . 要做的一件事是检查Moq等模拟框架。
Another thing I recently did was I added an overloaded constructor (dependency injection) that takes a HttpMessageInvoker
object (note HttpClient
derives from this). 我最近做的另一件事是我添加了一个HttpMessageInvoker
对象的重载构造函数(依赖注入)(注意HttpClient
从此派生)。 This way I could instantiate the class with my own response message: 这样,我可以使用自己的响应消息实例化该类:
public class MyLoader()
{
protected HttpMessageInvoker MessageInvoker { get; set; }
private HttpRequestMessage requestMessage;
public MyLoader() // default constructor
{
MessageInvoker = new HttpClient();
}
public MyLoader(HttpMessageInvoker httpMessageInvoker)
{
MessageInvoker = httpMessageInvoker;
}
public object DoSomething()
{
var response = await MessageInvoker.SendAsync(requestMessage, cancellationTokenSource.Token);
}
Here is my mock message invoker: 这是我的模拟消息调用程序:
public class MockMessageInvoker : HttpMessageInvoker
{
public string ResponseString { get; set; }
public MockMessageInvoker(string responseString)
: base(new HttpClientHandler())
{
ResponseString = responseString;
}
public override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
return Task.Run<HttpResponseMessage>(() =>
{
HttpResponseMessage responseMessage = new HttpResponseMessage(
System.Net.HttpStatusCode.OK);
var bytes = Encoding.ASCII.GetBytes(ResponseString);
var stream = new System.IO.MemoryStream(bytes);
responseMessage.Content = new StreamContent(stream);
return responseMessage;
});
}
}
I can call it all like so: 我可以这样称呼它:
MyLoader loader = new MyLoader(new MockMessageInvoker(validJsonResponse));
loader.DoSomething() // I've removed the dependency on the service and have control of the content in the response
It's quick and dirty, but does the trick. 它既快又脏,但是可以解决问题。
Hope this helps. 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.