9

I have got some code, which is using HttpWebRequest class's .BeginGetResponse() method and it is asynchronous. Also, I am using Microsoft's Unit Test App project for testing application.

The problem is that test framework does not waiting for end of running asynchronous code, so I can not check its result.

How should I test asynchronous code using Unit Test App project? I'm not using async/await modificators.

5
  • 1
    have you thoguht about using mocks for the web class/methods? Commented Jun 19, 2013 at 8:15
  • Unit testing other .Net specific code atleast like HttpWebRequest class may not sound good. Because you are just unit testing your module , thinking that what if the other module return valid value , invalid value and throw expcetion. So it would be better if you could mock the HttpWebRequest and just test your logic. Commented Jun 19, 2013 at 8:15
  • Yep, I am using mocks: server returns JSON to me, so I use mocks JSONs for passing it to the parsing module. But now I need to add queries caching to my API implementation, so I need to check how it's working without debugging each time. Commented Jun 19, 2013 at 8:18
  • If your test requires outsides resources like a databases or a network connection it no longer a unit test but already an integration test. A unit test framework might not be the right tool. Commented Jun 19, 2013 at 8:18
  • You should mock your objects. Check stackoverflow.com/questions/2113697/… Commented Jun 19, 2013 at 8:19

3 Answers 3

5

Update Answer
The original answer was quite an old one, before async and await were prevalent. I'd now recommend using them, by writing something like:

[TestMethod] public async Task RunTest() { var result = await doAsyncStuff(); // Expectations } 

There's a good article that covers this in depth Async Programming : Unit Testing Asynchronous Code

Old Answer

I would tend to something simple like using a polling loop and checking a flag that would be set in the async code or you could use reset events. A simple example using threads:

[TestMethod] public void RunTest() { ManualResetEvent done = new ManualResetEvent(false); Thread thread = new Thread(delegate() { // Do some stuff done.Set(); }); thread.Start(); done.WaitOne(); } 

You'll need to think about exceptions and use a try/finally and report the errors to do this properly, but you get the idea. This method however might not suit if you're doing lots of async stuff over and over, unless you fancy pushing this into a reusable method.

Sign up to request clarification or add additional context in comments.

4 Comments

Good idea, that works great for me! Thank you :) P.S. you got error in while(asyncDone) it should negate condition: while(!asyncDone)
Why poll when there are plenty of better ways to wait for asynchronous code to complete. (Manual/AutoResetEvent, Monitor, etc.) or better yet if you are going to use something like the above, why not just thread.Join()?
To expand on comment from @Iridium: or use async/await... (well actually Task.Wait())
@Iridium: All good suggests, Updated my answer to reflect one of them.
2

You could also use async/await pattern (using the HttpWebRequest wrapper from the Microsoft.Bcl.Async nuget package). This will also neatly handle any exceptions that occur in your background thread.

For example:

[TestMethod] public void RunTest() { bool asyncDone = false; // this is a dummy async task - replace it with any awaitable Task<T> var task = Task.Factory.StartNew(() => { // throw here to simulate bad code // throw new Exception(); // Do some stuff asyncDone = true; }); // Use Task.Wait to pause the test thread while the background code runs. // Any exceptions in the task will be rethrown from here. task.Wait(); // check our result was as expected Assert.AreEqual(true, asyncDone); } 

Comments

0

it's late but I guess this would be much more readable and authentic

await Task.Delay(TimeSpan.FromSeconds(5)); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.