Archive

Posts Tagged ‘vs2012’

Unit testing async Functions in VS2012

August 20th, 2012 No comments

In an attempt to get a jump start on writing Windows Store apps (is that what we’re calling them now?), I created a simple library targeting WinRT with some unit tests over the weekend. During that process, I got stumped for a good hour on how to properly write a unit test for an async function.

Let’s me walk you through this:

First: This is the code that I started with.

and I eventually found that you create your unit test like this

Note that the test itself is async and returns a Task. This is a requirement for the unit test. If the unit test returns void, you will not get a compile error, but the unit test will not show up in the Unit Test Explorer window.

The above code; however, doesn’t compile for a different reason.

The logic behind this is that you can only await something that returns a Task because of the way the framework works. The first hits in google said to do this:

Using the static function Run() against the function I wanted to execute would allow the test to wait on said function. Here’s where I ran into a peculiar issue (one which I, of course, cannot reproduce now that I’m trying to blog about it). It would compile and run, but when I hit the first await in the called function, the unit test would immediately return. Thus my test would always pass because no exception was thrown, no data every processed after the await, etc.

What I eventually discovered was that instead of wrapping the void function with Task.Run, I should make the function return Task instead:

After that update, my tests started waiting like they were supposed to.

Bonus:
There is a good follow up discussion on Stack Overflow about returning void vs returning a Task and what the purpose of even allowing an async void function is.

Categories: Coding Tags: , ,

Shim Example – Not ShimDateTime

June 12th, 2012 No comments

I spent some time today writing unit tests using the new Fakes framework in VS2012.  It took me a little bit to figure out exactly what was going on and I didn’t find any examples to help along the way (other then the normal ShimDateTime example).  Either my google-foo is off, or there just isn’t much out there yet, so I figured I would post a quick example to help get you started.

First step:   To create a Fake of a system assembly (or any assembly for that matter), right click on the reference in the unit test project references and click “Add Fakes Assembly”.  That will generate a Fakes assembly and add it to your project.  Once that is created, all namespaces in the original assembly will now have a corresponding .Fakes namespace. (e.g  System.IO.Fakes)

In this example, I have a function that cleans up some temporary data that my application creates.  I want to assert that that function does not throw exceptions if, for some reason, the temp folders cannot be deleted.

To start using the Shim objects, I need to define my ShimsContext.

 

This context keeps the shim scoped to this unit test or a subset of the unit test.  If the context is not defined, you’ll get an error when running the test.  I’m very glad that Microsoft set up the Shims in this fashion.  The reason being is that Shims are AppDomain wide, and left unchecked, could change how all of your unit tests execute.  That would lead to a lot of weird issues that would be hard to track down as you’re executing your unit test suite.   How would you like it, if your unit test was throwing IO exceptions when run on the build server, but when you run that isolated test on your machine, it runs perfectly?  I’d be pulling my hair out after 10 minutes most likely.

 

Now that I’ve wrapped my unit test in a ShimsContext, I can get to work on the meat of my unit test.  We’ve already created the fakes assembly for System, so it’s a matter of getting the Shim object for DirectoryInfo and returning what I want it to, in this case, throwing an exception.

 

I use the shim class for DirectoryInfo and set the AllInstnaces.DeleteBoolean property to my Action.  One thing to note: it appears that the naming convention is FunctionArg0Arg1 on the Shim properties.  Make sure you are setting the action for the specific function override that you’re using,  and not the first one you find.  For DirectoryInfo.Delete, there was both a Delete and a DeleteBoolean.     The AllInstances property allows me to state that any instance of this class follows this rule, not just a specific instance.   From there, setting the override is a simple lambda expression to define the Action.  (Instance, Parameters ) => { function; }.  I can’t think of any easier way to express my goal as a developer then that.

If you have not looked into the new testing features of VS2012, I would suggest that you watch this Tech-Ed presentation by Peter Provost.  It’s a great primer on the new features.   I have been very impressed by the Fakes framework so far and the Shim feature just knocks it out of the park.  All in all, once you get the basic syntax of Fakes, it will become your new best friend while writing unit tests.

 

 

Categories: Coding Tags: ,