単体テストのデバッグ中にブレークポイントがない場合に例外がスローされる理由がわかりませんでした。ただし、次の行にブレークポイントを設定してデバッグすると、問題なく実行されます。
これが私のコードです。
MainPageViewModel.cs
public class MainPageViewModel
{
public async Task<IEnumerable<Event>> GetAllEvents()
{
WebClient client = new WebClient();
string xmlDoc = await FXNewsAlert.Misc.Extensions.DownloadStringTask(client, new Uri("http://www.forexfactory.com/ffcal_week_this.xml")); //breakpoint here
var events = XDocument.Parse(xmlDoc)
.Descendants("event")
.Select(n => new Event
{
Title = n.Element("title").Value,
Country = n.Element("country").Value,
DateTime = this.ToLocalTime(String.Format("{0} {1}", n.Element("date").Value, n.Element("time").Value)),
Impact = n.Element("forecast").Value,
Forecast = n.Element("forecast").Value,
Previous = n.Element("previous").Value
}).ToList();
return events;
}
}
EventsTest.cs
[TestClass]
public class EventsTest : WorkItemTest
{
[TestMethod]
[Asynchronous]
public async void GetAllEventsTest()
{
MainPageViewModel vm = new MainPageViewModel();
IEnumerable<Event> events = await vm.GetAllEvents(); //WebException is thrown here.
Assert.IsTrue(events.Count() > 0);
EnqueueTestComplete();
}
}
私の推測では、どうにかして URL をロードするのに時間がかかるので、ブレークポイントを設定することで余分な時間を与えて、ダウンロードしている xml を時間通りに完了することができるようにします。
でも実際は非同期メソッドなので関係ないですよね?私は今かなり迷っています。どんな助けでも大歓迎です。
編集: DownloadStringTask の実装
public static Task<string> DownloadStringTask(this WebClient webClient, Uri uri)
{
var tcs = new TaskCompletionSource<string>();
webClient.DownloadStringCompleted += (s, e) =>
{
if (e.Error != null)
{
tcs.SetException(e.Error);
}
else
{
tcs.SetResult(e.Result);
}
};
webClient.DownloadStringAsync(uri);
return tcs.Task;
}
System.Net.WebException の StackTrace
System.Net.Browser.AsyncHelper.BeginOnUI (SendOrPostCallback beginMethod、オブジェクト状態) で System.Net.Browser.ClientHttpWebRequest.EndGetResponse (IAsyncResult asyncResult) で System.Net.WebClient.GetWebResponse (WebRequest 要求、IAsyncResult 結果) で System.Net .WebClient.DownloadBitsResponseCallback(IAsyncResult result) --- 例外がスローされた前の場所からのスタック トレースの終わり --- System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) で System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(タスク task) で System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()
at FXNewsAlert.Resources.MainPageViewModel.<GetAllEvents>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() で FXNewsAlertTest.UnitTests.EventsTest.d__0.MoveNext()