Thursday, August 9, 2012

What’s new in ApprovalTests.Net v.20?

ASP routing support

As community contributor, Krzysztof Koźmic  said in his NDC talk
Using ApprovalTests makes what was implicit,
explicit so that the item can now be tested
Inspired by his talk, Jim Counts and I created a new method in AspApprovals to make the formerly implicit ASP routing explicit and now easily able to be tested.  Here’s an example
var urls = new[] {"/Home/Index/Hello", "/"};
AspApprovals.VerifyRouting(MvcApplication.RegisterRoutes, urls);


In the sample above, the delegate (MvcApplication.RegisterRoutes) will be invokes against a mock route collection, and then fed the URLs provided.  A sample output would look like this:

/Home/Index/Hello => [[controller, Home], [action, Index], [id, Hello]] 
/ => [[controller, Cool], [action, Index], [id, ]]

Event approvals

Similar to the example above, another aspect of code which is often hidden (or implicit) is which events are wired-up to your form.  This can be particularly troublesome when changing an existing, unfamiliar piece of code.  For example, it it easy to accidentally remove a button-click event.

Event approvals allows you to easily lock down existing events which are associated with an object or a form.  To do this, simply call the following:

EventApprovals.VerifyEvents(myObject);

This new method will only allow you to verify events which are directly associated to the object which is passed in.  Unfortunately, many times you don’t want to say ‘What are the events associated with this button"? rather you actually want to say ‘What are the events associated to this form, even though the button is on the form and the event is associated to the button (rather than the form)?’  This is now no problem, since we took this scenario into consideration and also created a convenience method for the latter scenario.

To test all the events on a form and its immediate children, simply call code as shown below:

WinFormsApprovals.VerifyEventsFor(new DemoForm());

WPF support for Controls

It’s always been possible to test WPF windows with a simple:

WpfApprovals.Verify(window);

This would render the window to a .png image and verify against .approved file.

But sometimes you want to scope smaller to an individual control. Unfortunately, we had previously neglected this scenario – no longer!  You can now test an individual WPF control with the same call as shown below:

var menu = new ContextMenu();
menu.Items.Add(new MenuItem() {Header = "Add Element"});
menu.Items.Add(new MenuItem() {Header = "Delete"});
menu.Items.Add(new MenuItem() {Header = "Edit"});
menu.IsOpen = true;
WpfApprovals.Verify(menu);

This code will produce a *.png image, such as the one shown below:
ApprovalsTest.TestContextMenu.approved

Entity Framework support

People have long pondered how to test Entity Framework.  We have talked about this before, but previously testing EF with ApprovalTests had always required a large number of steps.  Now you can test EF by simply calling

using (var db = new ModelContainer())
{
    EntityFrameworkApprovals.Verify(db, CreateCompanyLoaderByName2(db, "Mic"));
}

This method will implement a ‘test-the-weather’ scenario which will verify the resulting SQL without the need to be able to connect to a database.  However, if this method fails, then it will connect to referenced database and will execute the generated query and will return extra information about WHY the test failed.  I plan to create more detailed tutorials on the inner workings of this new method soon.

Let’s give you one more look at this method signature.

public static void Verify<T>(ObjectContext db, IQueryable<T> queryable)

Email support for attachments

Previously, we added the method

EmailApprovals.Verify(message);

Unfortunately, when the email message contained attachments, then the GUIDs that those attachments created caused issues with test output because they were not consistent over multiple test runs.  This bug has been fixed in this release.  To learn more about approving email messages, watch this video.

Testing Email with ApprovalTests

FileLauncher with DelayReporter

There has been a great deal of demand to use Cassini-dev after Jim Counts demo’d it during his ASPConf video on testing ASP.MVC views. Unfortunately, when using this method it’s a bit tricky to use a file launcher, since the web server dies BEFORE the browser can hit it.  We came up with a simple solution which adds a tiny delay into the method execution so that this is no longer an issue.

[UseReporter(typeof(FileLauncherWithDelayReporter))]

Well, that’s all for this release. As always, if you have any questions about ApprovalTests, tweet them with the hashtag #ApprovalTests, I monitor that and will answer you promptly.

Happy testing.