[英]Exception thrown during unit test when breakpoint is not set
I could not figure out why the exception is thrown when I don't have a breakpoint during debugging for my unit test. 我无法弄清楚为什么在调试单元测试期间没有断点时会引发异常。 However, when I debug with breakpoint set at the following line, it runs okay.
但是,当我在下一行设置断点进行调试时,它可以正常运行。
Here is my code. 这是我的代码。
MainPageViewModel.cs 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 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();
}
}
My guess is that somehow it takes time to load the url, so by having a breakpoint it gives that extra time to so the xml I'm downloading could be completed on time. 我的猜测是,以某种方式加载URL会花费一些时间,因此通过具有断点,它可以给额外的时间,以便可以及时完成我正在下载的xml。
But it is actually an async method, so it doesn't matter right? 但这实际上是一个异步方法,所以没关系吧? I'm pretty much lost now.
我现在迷路了。 Any help would be greatly appreciated.
任何帮助将不胜感激。
Edit: Implementation for DownloadStringTask 编辑: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;
}
StackTrace for the System.Net.WebException System.Net.WebException的StackTrace
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state) at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result) at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result) --- 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() 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
在System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod,Object state)在System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)在System.Net.WebClient.GetWebResponse(WebRequest request,IAsyncResult result) .WebClient.DownloadBitsResponseCallback(IAsyncResult结果)-从上一个引发异常的位置开始的堆栈跟踪-在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在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() 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() at FXNewsAlertTest.UnitTests.EventsTest.d__0.MoveNext() 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()
I have a feeling that something is going wrong in FXNewsAlert, the implementation of which isn't presented above. 我感觉FXNewsAlert出现了问题,上面没有介绍其实现。 I recommend digging into (or replacing)
FXNewsAlert.Misc.Extensions.DownloadStringTask()
. 我建议深入(或替换)
FXNewsAlert.Misc.Extensions.DownloadStringTask()
。 My guess is that it's yielding before the its completed its download. 我的猜测是它在完成下载之前就已经屈服了。
In order to test this code, I first created an Event class to contain the data and minimize changes to your code: 为了测试此代码,我首先创建了一个Event类来包含数据并最小化对代码的更改:
public class Event
{
public string Title { get; set; }
public string Country { get; set; }
public DateTime DateTime { get; set; }
public string Impact { get; set; }
public string Forecast { get; set; }
public string Previous { get; set; }
}
I then slightly modified your code to usr the WebClient's DownloadStringTaskAsync()
method: 然后,我对您的代码进行了少许修改,使其使用usr WebClient的
DownloadStringTaskAsync()
方法:
public class MainPageViewModel
{
public async Task<IEnumerable<Event>> GetAllEvents()
{
WebClient client = new WebClient();
// HACK: Don't have access to the implementation to FXNewsAlert...
//string xmlDoc = await FXNewsAlert.Misc.Extensions.DownloadStringTask(
// client, new Uri("http://www.forexfactory.com/ffcal_week_this.xml")); //breakpoint here
string xmlDoc = await client.DownloadStringTaskAsync(
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 = DateTime.Parse(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;
}
}
Rather than create a test project, I whipped up the following console app: 我创建了以下控制台应用程序,而不是创建测试项目:
class Program
{
static void Main(string[] args)
{
var vm = new MainPageViewModel();
var task = vm.GetAllEvents();
task.Wait();
foreach (Event e in task.Result)
{
Console.WriteLine("{0} [{1}]", e.Title, e.DateTime);
Console.WriteLine("Forecast: {0} (Previous: {1})", e.Forecast, e.Previous);
Console.WriteLine();
}
}
}
This code executes fine with and without a breakpoint. 无论有没有断点,此代码都能正常执行。
Change your test method from async void
to async Task
. 将测试方法从
async void
更改为async Task
。
This won't clear up the WebException
, but it should make it consistent so you can debug it. 这不会清除
WebException
,但是应该使它保持一致,以便您可以对其进行调试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.