如何在Windows Phone上使用Web服务的单元测试方法?

时间:2014-02-27 05:12:55

标签: c# web-services unit-testing windows-phone-8 mocking

我正在开发一个从外部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;
         }
    }

谢谢!

2 个答案:

答案 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

它快速而肮脏,但可以解决问题。

希望这有帮助。