[英]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.