我正在开发一个从外部Web服务API检索信息的项目,但我不确定我应该如何测试它,我在测试方面很新,我只做了几个单元测试,但据我所知,我必须模拟web服务功能,我一直在寻找有关此主题的信息,但尚未找到任何适用于Windows Phone的信息。这类案件的标准程序是什么?
这是我想要测试的简单版本:
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;
}
}
谢谢!
答案 0 :(得分:1)
Decouple来自其依赖项的代码:make content loading及其反序列化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;
}
}
答案 1 :(得分:0)
可能有用的第一件事是理解和使用依赖注入。基本上采用对象/方法/等的任何依赖关系和(如它所述)将它们注入对象/方法/等。例如,您很难确定如何测试该方法,因为该方法依赖于能够访问Web服务。在此之后你可以做几件事。
要做的一件事就是查看模拟框架,例如Moq。
我最近做的另一件事是我添加了一个带有HttpMessageInvoker
对象的重载构造函数(依赖注入)(注意HttpClient
派生自此)。这样我就可以使用自己的响应消息实例化该类:
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);
}
这是我的模拟消息调用者:
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;
});
}
}
我可以这样称呼它:
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
它快速而肮脏,但可以解决问题。
希望这有帮助。