繁体   English   中英

使用可移植类库进行异步单元测试

[英]Async unit testing with portable class libraries

我有一个便携式类库,需要至少针对.net 4.5和Silverlight 5.我遇到了一个问题,试图在VS 2012中编写MSTest单元测试,因为我的库不使用新的async / await范例。 有什么方法可以测试这种方法吗?

public static void Get(string uri, string acceptHeader, Action<string> callback)
{
    var request = (HttpWebRequest)WebRequest.Create(uri);
    request.Accept = acceptHeader;        

    request.BeginGetResponse(o =>
    {
        var r = o.AsyncState as HttpWebRequest;
        try
        {
            var response = r.EndGetResponse(o);
            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                callback(sr.ReadToEnd());
            }
        }
        catch (Exception ex)
        {
            throw new WebException(string.Format("Unable to access {0}", uri), ex);
        }
    }, request);
}

只是无法抗拒重构代码。 您可以使用闭包执行以下操作

public static void Get(string uri, string acceptHeader, Action<string> callback)
{
    var request = (HttpWebRequest)WebRequest.Create(uri);
    request.Accept = acceptHeader;        

    request.BeginGetResponse(o =>
    {
        try
        {
            var response = request.EndGetResponse(o);
            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                callback(sr.ReadToEnd());
            }
        }
        catch (Exception ex)
        {
            throw new WebException(string.Format("Unable to access {0}", uri), ex);
        }
    }, null);
}

但是,在一天结束时,您可以执行以下操作

public async static void Get(string uri, string acceptHeader, Action<string> callback)
{
    var request = (HttpWebRequest)WebRequest.Create(uri);
    request.Accept = acceptHeader;        
    var response = await Task.Factory.FromAsync(
                             request.BeginGetRequestStream ,
                             request.EndGetRequestStream ,
                             uri,
                             null);
    using (var sr = new StreamReader(response))
    {
        callback(sr.ReadToEnd());
    }
}

好的,这就是我要怎么做的

void Main()
{
    {...}
    var request = (HttpWebRequest)WebRequest.Create(uri);
    request.Accept = acceptHeader;
    var response = await request.DownloadStringTaskAwait();
    DoSomeStuff(response);
}

// Define other methods and classes here
public static class HttpWebRequestExtension
{
    public async Task<string> DownloadStringTaskAwait(this HttpWebRequest request)
    {
        var response = await Task.Factory.FromAsync<Stream>(
                            request.BeginGetRequestStream,
                            request.EndGetRequestStream,
                            null);
                    using (var sr = new StreamReader(response))
                    {
                         return sr.ReadToEnd();
                    }
            }

}

首先,我建议你重新考虑async / await 这是未来的潮流。 Microsoft.Bcl.Async为面向.NET 4.5和SL5的可移植库提供async支持。

但是如果你不想这样做,你仍然可以使用async单元测试:

[TestMethod]
public async Task Get_RetrievesExpectedString()
{
  var tcs = new TaskCompletionSource<string>();
  var client = new ... // arrange

  client.Get(uri, acceptHeader, result =>
  {
    tcs.SetResult(result);
  });
  var actual = await tcs.Task;

  Assert.AreEqual(expected, actual);
}

或者如果你想,你可以做“老派”:

[TestMethod]
public void Get_RetrievesExpectedString()
{
  var mre = new ManualResetEvent(initialState: false);
  string actual = null;
  var client = new ... // arrange

  client.Get(uri, acceptHeader, result =>
  {
    actual = result;
    mre.Set();
  });
  mre.WaitOne();

  Assert.AreEqual(expected, actual);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM