<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Testing &amp; Debugging</title>
        <link>http://geekswithblogs.net/chrisfalter/category/7528.aspx</link>
        <description>A good developer knows how to test and debug!</description>
        <language>en-US</language>
        <copyright>Chris Falter</copyright>
        <managingEditor>chrisfalter@yahoo.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>How to Use Extension Methods and Lambda Expressions to Write Elegant Unit Tests</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2009/12/30/use-extension-methods-and-lambdas-to-write-elegant-unit-tests.aspx</link>
            <description>&lt;div&gt;Suppose you have to write a test to verify that an edit form will throw a certain exception under certain conditions.  If you don't use VB 9 features, you might end up with this effusion of verbosity:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;
&lt;div style="background: none repeat scroll 0% 0% transparent; font-family: courier new; -moz-background-inline-policy: continuous; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Try&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            editForm.Save(MyDataContext)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Throw New&lt;/span&gt; AssertFailedException(&lt;span style="color: rgb(163, 21, 21);"&gt;"Save should have thrown an exception"&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Catch&lt;/span&gt; ex &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;If Not&lt;/span&gt; (ex.GetType().Equals(&lt;span style="color: blue;"&gt;GetType&lt;/span&gt;(BusinessOperationException))) &lt;span style="color: blue;"&gt;Then&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
                &lt;span style="color: blue;"&gt;Dim&lt;/span&gt; errorMessage = &lt;span style="color: blue;"&gt;String&lt;/span&gt;.Format(&lt;span style="color: rgb(163, 21, 21);"&gt;"Save should should have thrown BusinessOperationException; threw {0} instead"&lt;/span&gt;, ex.GetType())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
                &lt;span style="color: blue;"&gt;Throw New&lt;/span&gt; AssertFailedException(errorMessage)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;If&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Dim&lt;/span&gt; bopException = &lt;span style="color: blue;"&gt;DirectCast&lt;/span&gt;(ex, BusinessOperationException)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            Assert.IsTrue(bopException.DataFormErrorInfo.SQLErrorInfo.ErrorMessage.Contains(&lt;span style="color: rgb(163, 21, 21);"&gt;"ERR_MEMBERSPECIFIEDMEMBERS_INVALID"&lt;/span&gt;))&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;End Try&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Of course, you could make the code a little simpler by not handling any exceptions of the wrong type, which would implicitly cause the test to fail if an exception of the wrong type is thrown:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;
&lt;div style="background: none repeat scroll 0% 0% transparent; -moz-background-inline-policy: continuous; color: black; font-family: courier new; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;
         &lt;span style="color: blue;"&gt;Try&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
             editForm.Save(MyDataContext) &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
             &lt;span style="color: blue;"&gt;Throw New&lt;/span&gt; AssertFailedException(&lt;span style="color: rgb(163, 21, 21);"&gt;"Save should have thrown an exception"&lt;/span&gt;)
&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
         &lt;span style="color: blue;"&gt;Catch&lt;/span&gt; ex &lt;span style="color: blue;"&gt;As&lt;/span&gt; BusinessOperationException
&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;span style="color: green;"&gt;            ' exceptions of other types are not handled&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
             Assert.IsTrue(ex.DataFormErrorInfo.SQLErrorInfo.ErrorMessage.Contains(&lt;span style="color: rgb(163, 21, 21);"&gt;"ERR_MEMBERSPECIFIEDMEMBERS_INVALID"&lt;/span&gt;))
&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
         &lt;span style="color: blue;"&gt;End Try&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;While this is better, the code is not without problems:&lt;/div&gt;
&lt;ul&gt;
    &lt;li&gt;The reader of this code has to infer that exceptions of a type other than BusinessOperationException will fail cause a test failure.  Yes, you can mitigate this by including a helpful comment--if you remember.  I'd rather not have to remember.&lt;/li&gt;
    &lt;li&gt;The intention of the test is buried inside the mechanics of the try/catch block.&lt;/li&gt;
    &lt;li&gt;The assertion about the state of the BusinessOperationException instance is not easy to follow, since the reader of the code has to walk a lengthy property hierarchy (DataFormErrorInfo =&amp;gt; SQLErrorInfo =&amp;gt; ErrorMessage).  This is a glaring violation of the &lt;a href="http://en.wikipedia.org/wiki/Law_Of_Demeter"&gt;Law of Demeter&lt;/a&gt;.  In addition, it is not self-evident from reading the code that DataFormErrorInfo.SQLErrorInfo.ErrorMessage would naturally be the location where one would find the argument to a SQL &lt;em&gt;raiserror&lt;/em&gt; call.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Prior to VB 9 it would have been very difficult to write this code with a smoother syntax due to the limitations of the language.  But now we can solve these problems by using lambda expressions and extension methods, as follows:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;
&lt;div style="background: none repeat scroll 0% 0% white; font-family: courier new; -moz-background-inline-policy: continuous; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Dim&lt;/span&gt; saveForm &lt;span style="color: blue;"&gt;As&lt;/span&gt; Action = &lt;span style="color: blue;"&gt;Function&lt;/span&gt;() &lt;span style="color: blue;"&gt;Me&lt;/span&gt;.Save(editForm)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        saveForm.ShouldThrow(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; BusinessOperationException).Where(&lt;span style="color: blue;"&gt;Function&lt;/span&gt;(e) e.DBExceptionCode.Contains(&lt;span style="color: rgb(163, 21, 21);"&gt;"ERR_MEMBERSPECIFIEDMEMBERS_INVALID"&lt;/span&gt;))&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Here the fact that the form's .Save() method should throw a BusinessOperationException with a &lt;span style="color: rgb(163, 21, 21);"&gt;"ERR_MEMBERSPECIFIEDMEMBERS_INVALID" &lt;/span&gt;exception code walks up to the reader and punches him in the face.  And that's what we want all of our code to do; pugnacious code is good code!  Moreover, the ShouldThrow() and Where() methods will emit useful, detailed messages for any error conditions.  Let's see how VB 9 helps us to work this magic.&lt;/div&gt;
&lt;h3&gt;&lt;strong&gt;Extension Methods&lt;/strong&gt;&lt;/h3&gt;
&lt;div&gt;An extension method acts as if it belongs to a type; thus you may create an extension method for a type even if you do not possess the type's source code.  Without extension methods, your only choice is to create a shared helper method that takes a type instance as a parameter.  For example, in earlier VB versions you could have written a shared &lt;em&gt;Throws()&lt;/em&gt; method that takes an Action delegate as a parameter.  However, the extension method has greater clarity and readability:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;table cellspacing="1" cellpadding="3" border="1" style="width: 845px; height: 135px;"&gt;
    &lt;caption&gt;Extension Methods vs. Shared/Static Methods&lt;/caption&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th scope="col"&gt;Coding Technique&lt;/th&gt;
            &lt;th style="width: 374px;" scope="col"&gt;Extension Method&lt;/th&gt;
            &lt;th scope="col"&gt;Shared Method&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;th scope="row"&gt;Syntax&lt;/th&gt;
            &lt;td style="text-align: center;"&gt;Subject + Verb + arguments/modifiers&lt;/td&gt;
            &lt;td style="text-align: center;"&gt;Verb + list of arguments&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;th scope="row"&gt;Example&lt;/th&gt;
            &lt;td style="text-align: center;"&gt;saveForm.ShouldThrow(Of BusinessOperationException)&lt;/td&gt;
            &lt;td style="text-align: center;"&gt;Throws(Of BusinessOperationException)(saveForm)&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;th scope="row"&gt;Readability&lt;/th&gt;
            &lt;td style="text-align: center;"&gt;Close to standard English - very readable&lt;/td&gt;
            &lt;td&gt;
            &lt;p&gt;Completely at odds with English grammar.  And when there are many arguments, which is the subject and which are modifiers?&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Ultimately an extension method is syntactical sugar; then again, a little sugar can help you bake some wonderful recipes.  So let's check it out.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;In the solution code above, the generic &lt;em&gt;ShouldThrow(Of TException)&lt;/em&gt; method is as an extension method to the .NET Action delegate.  Let me pause for a moment to let that concept sink in; we are writing code that extends a built-in .NET type.  And that type isn't even a class; it's a delegate!  Clearly, extension methods open up a new realm of possibilities to us.  Decorating a standard shared method with the &lt;strong&gt;System.Runtime.CompilerServices.&lt;/strong&gt;&lt;strong&gt;ExtensionAttribute&lt;/strong&gt; turns it into a method that behaves as if it were a member of the type of its first argument.  Thus the first argument to the &lt;em&gt;ShouldThrow&lt;/em&gt; method in Blackbaud.AppFx.UnitTesting/AssertExtensions.vb is of type Action delegate:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;
&lt;div style="background: none repeat scroll 0% 0% white; font-family: courier new; -moz-background-inline-policy: continuous; color: black;"&gt;    &amp;lt;Extension()&amp;gt; _&lt;/div&gt;
&lt;/div&gt;
&lt;div style="background: none repeat scroll 0% 0% white; font-family: courier new; -moz-background-inline-policy: continuous; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt; ShouldThrow(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception)(&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; workToDo &lt;span style="color: blue;"&gt;As&lt;/span&gt; Action) &lt;span style="color: blue;"&gt;As&lt;/span&gt; TException&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Dim&lt;/span&gt; errorMessage &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;New&lt;/span&gt; StringBuilder(&lt;span style="color: rgb(163, 21, 21);"&gt;"An exception of type "&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.Append(&lt;span style="color: blue;"&gt;GetType&lt;/span&gt;(TException))&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.Append(&lt;span style="color: rgb(163, 21, 21);"&gt;" should have been thrown, but wasn't.  Test method info follows..."&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.AppendLine()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.AppendCallingMethodInfo()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Return&lt;/span&gt; ShouldThrow(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException)(workToDo, errorMessage.ToString())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &amp;lt;Extension()&amp;gt; _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt; ShouldThrow(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception)(&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; workToDo &lt;span style="color: blue;"&gt;As&lt;/span&gt; Action, &lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; errorMessage &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;String&lt;/span&gt;) &lt;span style="color: blue;"&gt;As&lt;/span&gt; TException&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Try&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            workToDo.Invoke()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Throw&lt;/span&gt; &lt;span style="color: blue;"&gt;New&lt;/span&gt; AssertFailedException(errorMessage)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Catch&lt;/span&gt; ex &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;If&lt;/span&gt; (&lt;span style="color: blue;"&gt;GetType&lt;/span&gt;(TException).Equals(ex.GetType)) &lt;span style="color: blue;"&gt;Then&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
                &lt;span style="color: blue;"&gt;Return&lt;/span&gt; ex&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;If&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Throw&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Try&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The .&lt;em&gt;ShouldThrow()&lt;/em&gt; method encapsulates all of the try/catch logic that had obfuscated the earlier versions of our test code.  Just specify the type of the exception that should be thrown when you call it, and it will do one of three things:&lt;/div&gt;
&lt;ul&gt;
    &lt;li&gt;return the thrown exception of the desired type,&lt;/li&gt;
    &lt;li&gt;rethrow a thrown exception of the wrong type, or&lt;/li&gt;
    &lt;li&gt;throw its own exception if an exception is not thrown.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;In VB an extension method must belong to a module.  (C# uses a static class.)  After you compile the module containing the &lt;em&gt;ShouldThrow()&lt;/em&gt; method, the .NET languages will allow you to use it as if it were actually a member of the Action delegate type.  An extension method does have a limitation that true members of a type do not have: it cannot access the non-public members of the type.  Alas, even magic has limits.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Another nice aspect of writing an extension method is that it will even show up in Intellisense!   Already the advantage of the the extension method is clear; if you were using an older-style shared method, Intellisense would not list it as a candidate for use with the Action delegate &lt;em&gt;saveAction&lt;/em&gt;.  &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;While an overload of the &lt;em&gt;ShouldThrow()&lt;/em&gt; method is available for those who wish to provide a custom error message, the default (parameterless) overload uses the &lt;em&gt;AppendCallingMethodInfo()&lt;/em&gt; method to incorporate the name, source file, and line number of the calling test method into a useful error message.  I recommend using the default overload of &lt;em&gt;ShouldThrow()&lt;/em&gt; for most situations, since it produces a very useful error message while keeping your code's syntax as simple as possible.  The alert reader will note that &lt;em&gt;AppendCallingMethodInfo()&lt;/em&gt; is implemented as an extension method to the StringBuilder class; the curious may read through AssertExtensions.vb source file to see how the info is extracted from a stack trace.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The AssertExtensions module also contains the .&lt;em&gt;Where()&lt;/em&gt; extension method overloads which, as we see from their first parameter, can be called on a generic exception.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="background: none repeat scroll 0% 0% white; font-family: courier new; -moz-background-inline-policy: continuous; color: black; font-size: 10pt;"&gt; &lt;/div&gt;
&lt;div style="background: none repeat scroll 0% 0% white; font-family: courier new; -moz-background-inline-policy: continuous; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;
    &amp;lt;Extension()&amp;gt; _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt; Where(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception) _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    (&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; ex &lt;span style="color: blue;"&gt;As&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; predicate &lt;span style="color: blue;"&gt;As&lt;/span&gt; Func(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;)) _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Dim&lt;/span&gt; errorMessage &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;New&lt;/span&gt; StringBuilder(&lt;span style="color: rgb(163, 21, 21);"&gt;"The "&lt;/span&gt; + &lt;span style="color: blue;"&gt;GetType&lt;/span&gt;(TException).ToString() + &lt;span style="color: rgb(163, 21, 21);"&gt;" did not satisfy the Where predicate.  Test method info follows..."&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.AppendLine()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.AppendCallingMethodInfo()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Return&lt;/span&gt; Where(ex, predicate, errorMessage.ToString())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &amp;lt;Extension()&amp;gt; _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt; Where(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception) _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    (&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; ex &lt;span style="color: blue;"&gt;As&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; predicate &lt;span style="color: blue;"&gt;As&lt;/span&gt; Func(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;), &lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; errorMessage &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;String&lt;/span&gt;) _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;If&lt;/span&gt; Predicate(ex) &lt;span style="color: blue;"&gt;Then&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Return&lt;/span&gt; &lt;span style="color: blue;"&gt;True&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Throw&lt;/span&gt; &lt;span style="color: blue;"&gt;New&lt;/span&gt; AssertFailedException(errorMessage)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;If&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The &lt;strong&gt;Func&lt;/strong&gt; keyword, new in VB 9, denotes a generic function delegate whose signature is determined by the types of the parameters.  The last parameter is the return type of the delegate, and the leading parameters before it (if any) specify the types of the input parameters. Applying this syntax to our code, we see that the parameter &lt;em&gt;&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; predicate &lt;span style="color: blue;"&gt;As&lt;/span&gt; Func(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;)&lt;/em&gt; denotes a delegate for a function that takes a generic &lt;em&gt;&lt;strong&gt;TException&lt;/strong&gt;&lt;/em&gt; argument and returns Boolean.   The &lt;em&gt;Where()&lt;/em&gt; method invokes the delegate and takes care of throwing an AssertFailedException with an appropriate message if the delegate returns False.  You will recall that the sample code used a lambda expression to create the delegate invoked by Where().&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Finally, the ability to write an extension method allows us to obey the Law of Demeter, even though we cannot modify the BBSolder-generated BusinessOperationException class.  In the unit test file, just define an extension method that traverses the properties:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="background: none repeat scroll 0% 0% white; font-family: courier new; -moz-background-inline-policy: continuous; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;Friend&lt;/span&gt; &lt;span style="color: blue;"&gt;Module&lt;/span&gt; BusinessOperationExceptionExtensions&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &amp;lt;Extension()&amp;gt; _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Friend&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt; DBExceptionCode(&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; ex &lt;span style="color: blue;"&gt;As&lt;/span&gt; BusinessOperationException) &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;String&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Return&lt;/span&gt; ex.DataFormErrorInfo.SQLErrorInfo.ErrorMessage&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Module&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now for any BusinessOperationException &lt;em&gt;ex&lt;/em&gt;, you can just call &lt;em&gt;ex.DbExceptionCode&lt;/em&gt; instead of traversing the various properties.  Sweet!&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Lambda Expressions&lt;/strong&gt;&lt;/h3&gt;
&lt;div&gt;According to &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb531253.aspx"&gt;MSDN&lt;/a&gt;, a lambda expression is "a function without a name that calculates and returns a single value."  Think of a lambda expression as an executable block of code that is defined in-line, rather than in a function that must be defined somewhere else.  A lambda expression can also make use of variables that are in scope at the point where it is defined.  Because a lambda expression helps you keep the flow of logic in one place and avoid the ceremony of passing parameters, it can serve as a powerful tool for simplifying your code.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;You will recall that in our sample code, the .&lt;em&gt;Where&lt;/em&gt; extension method processes a lambda expression:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;em&gt;.Where(&lt;span style="color: blue;"&gt;Function&lt;/span&gt;(e) e.DBExceptionCode.Contains(&lt;span style="color: rgb(163, 21, 21);"&gt;"ERR_MEMBERSPECIFIEDMEMBERS_INVALID"&lt;/span&gt;))&lt;/em&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The &lt;strong&gt;Function&lt;/strong&gt; keyword indicates that the expression which follows is a lambda.  Behind the scenes, the VB compiler will do the following:&lt;/div&gt;
&lt;ul&gt;
    &lt;li&gt;build an anonymous function that takes a parameter of type BusinessOperationException and returns Boolean; the lambda expression then becomes the body of the function. &lt;/li&gt;
    &lt;li&gt;infer that the generic type TException declared in the .Where() method definition will be of type BusinessOperationException in this block of code. &lt;/li&gt;
    &lt;li&gt;build a delegate to that anonymous function, and then pass that delegate as an argument to the .&lt;em&gt;Where&lt;/em&gt; extension method, which has a &lt;em&gt;&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; predicate &lt;span style="color: blue;"&gt;As&lt;/span&gt; Func(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;)&lt;/em&gt; parameter. &lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;And you thought you worked hard!  Well, why not let the compiler do the hard work for you?  You could think of a lambda expression as a way to get the compiler to handle all the plumbing chores of function bodies and delegates, while leaving just the essence of the logic visible in your code. &lt;/div&gt;
&lt;h3&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h3&gt;
&lt;div&gt;Extension methods and lambda expressions can help you write code that is more succinct, more readable, and more powerful.  &lt;a target="_blank" href="http://blogs.msdn.com/ericwhite/pages/fp-tutorial-vb.aspx"&gt;According to Microsoft's Eric White&lt;/a&gt;, "Functional Programming (FP) has the potential to reduce program line count by 20% to 50%, reduce bugs and increase robustness, and move us in the direction of taking advantage of multiple core CPUs."  In this article we saw how extension methods and lambda expressions, which are important parts of the VB functional programming toolkit, made the sample test code more readable and succinct.  Of course these new techniques are not a golden hammer that can be used everywhere; nevertheless, be alert for opportunities to use them in the test code you write.&lt;/div&gt;
&lt;h3&gt;&lt;strong&gt;Further Reading&lt;/strong&gt;&lt;/h3&gt;
&lt;div&gt;&lt;a target="_blank" href="http://blogs.msdn.com/vbteam/pages/articles-about-extension-methods.aspx"&gt;Visual Basic Team Blog: Articles about Extension Methods&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/magazine/cc163362.aspx"&gt;Basic Instincts: Lambda Expressions&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;&lt;strong&gt;Source Listing for AssertExtensions.vb&lt;/strong&gt;&lt;/h3&gt;
&lt;div style="background: none repeat scroll 0% 0% white; font-family: courier new; -moz-background-inline-policy: continuous; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;Imports&lt;/span&gt; System.Diagnostics&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;Imports&lt;/span&gt; System.Runtime.CompilerServices&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;Imports&lt;/span&gt; System.Text&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Module&lt;/span&gt; AssertExtensions&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Verifies that a specific method call throws an exception of a specific type&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;typeparam name="TException"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The type of exception the method call is expected to throw&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name="workToDo"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;delegate to method call which is expected to throw an exception&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' instance of exception thrown by the Action&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' This method will re-throw any exceptions of a type other than that designated by the generic TException.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' If the Action does not throw any exceptions, this method will throw an AssertFailedException.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &amp;lt;Extension()&amp;gt; _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt; ShouldThrow(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception)(&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; workToDo &lt;span style="color: blue;"&gt;As&lt;/span&gt; Action) &lt;span style="color: blue;"&gt;As&lt;/span&gt; TException&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Dim&lt;/span&gt; errorMessage &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;New&lt;/span&gt; StringBuilder(&lt;span style="color: rgb(163, 21, 21);"&gt;"An exception of type "&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.Append(&lt;span style="color: blue;"&gt;GetType&lt;/span&gt;(TException))&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.Append(&lt;span style="color: rgb(163, 21, 21);"&gt;" should have been thrown, but wasn't.  Test method info follows..."&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.AppendLine()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.AppendCallingMethodInfo()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Return&lt;/span&gt; ShouldThrow(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException)(workToDo, errorMessage.ToString())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Verifies that a specific method call throws an exception of a specific type&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;typeparam name="TException"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The type of exception the method call is expected to throw&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name="workToDo"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;delegate to method call which is expected to throw an exception&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name="errorMessage"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;user-defined error message if expected exception not thrown&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' instance of exception thrown by the Action&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' This method will re-throw any exceptions of a type other than that designated by the generic TException.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' If the Action does not throw any exceptions, this method will throw an AssertFailedException.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &amp;lt;Extension()&amp;gt; _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt; ShouldThrow(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception)(&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; workToDo &lt;span style="color: blue;"&gt;As&lt;/span&gt; Action, &lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; errorMessage &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;String&lt;/span&gt;) &lt;span style="color: blue;"&gt;As&lt;/span&gt; TException&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Try&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            workToDo.Invoke()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Throw&lt;/span&gt; &lt;span style="color: blue;"&gt;New&lt;/span&gt; AssertFailedException(errorMessage)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Catch&lt;/span&gt; ex &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;If&lt;/span&gt; (&lt;span style="color: blue;"&gt;GetType&lt;/span&gt;(TException).Equals(ex.GetType)) &lt;span style="color: blue;"&gt;Then&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
                &lt;span style="color: blue;"&gt;Return&lt;/span&gt; ex&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;If&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Throw&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Try&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &amp;lt;Extension()&amp;gt; _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Sub&lt;/span&gt; AppendCallingMethodInfo(&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; sb &lt;span style="color: blue;"&gt;As&lt;/span&gt; StringBuilder, &lt;span style="color: blue;"&gt;Optional&lt;/span&gt; &lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; howManyFramesBack &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;Integer&lt;/span&gt; = 1)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: green;"&gt;' how far back is from the perspective of the caller of this method. +1 gets us back to the frame of &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: green;"&gt;' this method's caller, then we continue from there&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        howManyFramesBack += 1&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Dim&lt;/span&gt; st &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;New&lt;/span&gt; StackTrace(fNeedFileInfo:=&lt;span style="color: blue;"&gt;True&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Dim&lt;/span&gt; sf = st.GetFrame(howManyFramesBack)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        sb.Append(&lt;span style="color: rgb(163, 21, 21);"&gt;"Test method: "&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        sb.Append(sf.GetMethod())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        sb.AppendLine()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        sb.Append(&lt;span style="color: rgb(163, 21, 21);"&gt;"FileName: "&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        sb.Append(sf.GetFileName())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        sb.AppendLine()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        sb.Append(&lt;span style="color: rgb(163, 21, 21);"&gt;"Line Number: "&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        sb.Append(sf.GetFileLineNumber())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Sub&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Verifies that an exception satisfies a predicate&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;typeparam name="TException"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The type of exception against which the predicate is applied&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name="ex"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The exception against which the predicate is applied (passed by compiler)&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name="predicate"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The condition which the exception must satisfy&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;True if exception satisfies predicate, otherwise an AssertFailedException is thrown&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Unlike the IEnumerable(Of T).Where extension method, this method does not return a subset from a set.  &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Instead it verifies that a particular instance of an exception satisfies a predicate.  This method is &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' designed to be used in conjunction with ShouldThrow to provide a fluent expression for a test.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;example&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Dim myAction As Action = (Function() MyMethod(myData))&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' myAction.ShouldThrow(Of SpecializedException)().Where(Function(ex) ex.SpecialProperty = "Hello")&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/example&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &amp;lt;Extension()&amp;gt; _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt; Where(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception) _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    (&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; ex &lt;span style="color: blue;"&gt;As&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; predicate &lt;span style="color: blue;"&gt;As&lt;/span&gt; Func(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;)) _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Dim&lt;/span&gt; errorMessage &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;New&lt;/span&gt; StringBuilder(&lt;span style="color: rgb(163, 21, 21);"&gt;"The "&lt;/span&gt; + &lt;span style="color: blue;"&gt;GetType&lt;/span&gt;(TException).ToString() + &lt;span style="color: rgb(163, 21, 21);"&gt;" did not satisfy the Where predicate.  Test method info follows..."&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.AppendLine()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        errorMessage.AppendCallingMethodInfo()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Return&lt;/span&gt; Where(ex, predicate, errorMessage.ToString())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Verifies that an exception satisfies a predicate, and throws exception with user-supplied message if not&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;typeparam name="TException"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The type of exception against which the predicate is applied&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name="ex"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The exception against which the predicate is applied (passed by compiler)&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name="predicate"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The condition which the exception must satisfy&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name="errorMessage"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;Message of AssertFailedException thrown if predicate fails&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;True if exception satisfies predicate, otherwise an AssertFailedException is thrown&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Unlike the IEnumerable(Of T).Where extension method, this method does not return a subset from a set.  &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Instead it verifies that a particular instance of an exception satisfies a predicate.  This method is &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' designed to be used in conjunction with ShouldThrow to provide a fluent expression for a test.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;example&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' Dim myAction As Action = (Function() MyMethod(myData))&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' myAction.ShouldThrow(Of MyException)().Where(Function(ex) ex.MyProp = "Hello", "MyProp wasn't 'Hello')&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/example&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;''' &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &amp;lt;Extension()&amp;gt; _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;Public&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt; Where(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException &lt;span style="color: blue;"&gt;As&lt;/span&gt; Exception) _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    (&lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; ex &lt;span style="color: blue;"&gt;As&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; predicate &lt;span style="color: blue;"&gt;As&lt;/span&gt; Func(&lt;span style="color: blue;"&gt;Of&lt;/span&gt; TException, &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;), &lt;span style="color: blue;"&gt;ByVal&lt;/span&gt; errorMessage &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;String&lt;/span&gt;) _&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;As&lt;/span&gt; &lt;span style="color: blue;"&gt;Boolean&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;If&lt;/span&gt; Predicate(ex) &lt;span style="color: blue;"&gt;Then&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Return&lt;/span&gt; &lt;span style="color: blue;"&gt;True&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;Else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;Throw&lt;/span&gt; &lt;span style="color: blue;"&gt;New&lt;/span&gt; AssertFailedException(errorMessage)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;If&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;End&lt;/span&gt; &lt;span style="color: blue;"&gt;Module&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt; &lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/137275.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2009/12/30/use-extension-methods-and-lambdas-to-write-elegant-unit-tests.aspx</guid>
            <pubDate>Wed, 30 Dec 2009 21:23:54 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/137275.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2009/12/30/use-extension-methods-and-lambdas-to-write-elegant-unit-tests.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/137275.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/137275.aspx</trackback:ping>
        </item>
        <item>
            <title>How to Reuse Code Without Creating an Implicit API</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2009/03/29/how-to-reuse-code-without-creating-an-implicit-api.aspx</link>
            <description>&lt;p&gt;I work for an ISV, and we have to be very cautious about the code that we declare with public scope.  If it's public, a customer can treat it as an API, which might not always be a good idea if the code is really just doing some internal task in a way that could easily change as we improve our software.  In other words, not all that is public should be an API.&lt;/p&gt;
&lt;p&gt;So what do you do if you need to share code across assembly boundaries?  Recently I was writing some unit tests for a class, and the tests needed access to a class method in order to imitate (and test) its behavior.  Of course this method was private--&lt;em&gt;of course!&lt;/em&gt;--so it appeared that I had to choose between 2 very unpalatable options:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Give the method public scope, which would make it visible to all our customers' implementations.  Essentially, this option would make the method part of our API.  Not happening.&lt;/li&gt;
    &lt;li&gt;Copy the 20 lines of code from the method, paste it into my new class, and supplicate the dark spirits of bad software design to supernaturally prevent the method from ever being modified.  But how could I perform the ritual without an eye of newt and toe of frog?*&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But appearances can be deceiving.  It turns out that the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx" target="_blank"&gt;InternalsVisibleToAttribute&lt;/a&gt;, introduced by Microsoft in .NET 2.0, solves the problem quite neatly.  Using this attribute, you can designate one or more friend assemblies that will be allowed access to classes, methods and properties in the target assembly that have friend scope, while all other code--including customer code--is denied access.&lt;/p&gt;
&lt;p&gt;Using the attribute is a piece of cake:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Mark any classes/methods/properties that need to be visible to other assemblies with "Friend" scope.&lt;/li&gt;
    &lt;li&gt;
    &lt;p&gt;Import the System.Runtime.CompilerServices namespace into your assembly's AssemblyInfo.vb file.&lt;/p&gt;
    &lt;blockquote&gt;
    &lt;p&gt;&lt;font color="#0000ff"&gt;Imports&lt;/font&gt; System.Runtime.InteropServices&lt;/p&gt;
    &lt;/blockquote&gt;&lt;/li&gt;
    &lt;li&gt;
    &lt;p&gt;In AssemblyInfo.vb, mark the assembly with the InternalsVisibleToAttribute for each friend assembly that should have access to the friend scope.&lt;/p&gt;
    &lt;blockquote&gt;
    &lt;p&gt;&amp;lt;Assembly: InternalsVisibleTo(&lt;font color="#800000"&gt;"MySystem.Assembly1"&lt;/font&gt;)&amp;gt; &lt;br /&gt;
    &amp;lt;Assembly: InternalsVisibleTo(&lt;font color="#800000"&gt;"MySystem.Assembly2"&lt;/font&gt;)&amp;gt;&lt;/p&gt;
    &lt;/blockquote&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you are working in C#, you will make your changes in the AssemblyInfo.cs file for the assembly that contains the code to be re-used, and you will use "using" instead of "Imports."&lt;/p&gt;
&lt;p&gt;So I could have my cake (re-use of existing code) &lt;em&gt;and&lt;/em&gt; shield it from inappropriate eyes at the same time.  While this technique is obviously useful for writing tests, it can be applied anywhere that code needs to be shared between your system's assemblies without exposing it customers as part of an API. &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;font size="1"&gt;* Not to mention the wool of bat and tongue of dog.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt; &lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/130511.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2009/03/29/how-to-reuse-code-without-creating-an-implicit-api.aspx</guid>
            <pubDate>Sun, 29 Mar 2009 19:44:23 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/130511.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2009/03/29/how-to-reuse-code-without-creating-an-implicit-api.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/130511.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/130511.aspx</trackback:ping>
        </item>
        <item>
            <title>Why You Should Consider Using FIT</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2008/02/05/119320.aspx</link>
            <description>&lt;p&gt;I was looking for ways to improve our development process when I stumbled across the Framework for Integrated Testing (FIT).  The rest of this post is the body of an email I recently sent to my manager.&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;The goal of the &lt;em&gt;Customer&lt;/em&gt; update is to migrate all their customizations to a new framework in a reliable and quick manner.  The major risks I have been able to identify are as follows:&lt;/font&gt;&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;Developers won’t be able to identify all the behaviors that need to migrate.&lt;/font&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;font face="Arial"&gt;Requirements are scattered.&lt;/font&gt; &lt;/li&gt;
        &lt;li&gt;&lt;font face="Arial"&gt;Code is not organized optimally.  Much business and workflow logic is scattered throughout the UI layer, in particular. Many customizations in domain logic are located in poor locations in the domain class hierarchy; the root domain object seems to have become a catch-all location for just about anything.&lt;/font&gt; &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;Manual regression testing will become a bottleneck.  It is already a serious bottleneck for other projects.&lt;/font&gt; &lt;/li&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;Poor code organization will be perpetuated into the new source code base.  As a result, the project will proceed more slowly (due to high bug rate and unnecessary complexity), and subsequent evolution of the code will be hampered as well.&lt;/font&gt; &lt;/li&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;Lack of an automated testing framework will impede any efforts to refactor code.  Since this project by definition requires an extensive reworking of our source code, this risk is quite serious.&lt;/font&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;font face="Arial"&gt;&lt;em&gt;Note to readers: I'm sure many of you have faced these kinds of challenges on one or more projects.  Read on to discover a framework that can help you can meet the challenges!&lt;/em&gt; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;While unit testing would go a long way toward addressing the third and fourth risks, it would not help us address the first 2 risks.  We can ask business analysts (BAs) to help developers identify migration requirements, but we don’t have a repository for storing these requirements.  Even if we implement such a repository, a developer must still translate requirements (in whatever form they exist) into unit tests, which introduces the possibility of error.  Finally, the unit tests are not visible to the BAs, so they cannot rely on them for regression testing.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;The &lt;a href="http://fit.c2.com/"&gt;Framework for Integrated Testing&lt;/a&gt; (FIT) seems to address all four of these risks quite adeptly.  Before I proceed, I should explain that FIT allows a non-developer to write requirements in tabular form.  FIT provides 3 types of test fixtures that can be used in a table:&lt;/font&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;A &lt;em&gt;ColumnFixture&lt;/em&gt; is useful for business rules, as it is used to declare a set of inputs and expected output(s).  For example, you could use a column fixture to declare that a dwelling in a particular location built in 1996 should have a BCEGS of 99, but if it is built in 2004 it should have a BCEGS of 4.  As the &lt;em&gt;Customer&lt;/em&gt; systems are replete with custom rules (such as underwriter referral rules), the ColumnFixture should prove very helpful.&lt;/font&gt; &lt;/li&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;A &lt;em&gt;RowFixture&lt;/em&gt; is ensures that data are being stored and retrieved correctly from a data repository.  While I see no need to test the data layer’s reliability with respect to standard data such as dwelling address (it has proven quite reliable for other projects), the RowFixture could help us with data that are unique to &lt;em&gt;Customer&lt;/em&gt; (such as subdivision).&lt;/font&gt; &lt;/li&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;An &lt;em&gt;ActionFixture&lt;/em&gt; is used to simulate workflow requirements.  For example, a tabular ActionFixture could state that when a user enters a dwelling limit of $10k and presses “Continue”, a certain error message should appear; when s/he enters a dwelling limit of 300k and presses “Continue”, the system advances to the Quote Summary page; and if s/he enters a dwelling limit of 1100k, the system advances to the Qualification Questions page (due to consent to rate rules).&lt;/font&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;font face="Arial"&gt;If we use the &lt;a href="http://msdn.microsoft.com/msdnmag/issues/05/02/ExcelUnitTests/default.aspx"&gt;WinFitRunnerLite&lt;/a&gt; tool, a BA can construct the test data tables in Excel, which may be more intuitive than writing them in Word and saving as HTML.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;A developer must write a test fixture in order to translate the test data into an actual test.  The test fixture will link to the domain, data, and controller/workflow libraries of the system under test, pass data from the test document’s tables to the appropriate methods, and evaluate the results against the BA-supplied expectations.  If we follow this approach, it will be impossible for a developer to embed workflow logic, rules, or domain logic in the UI (a big win!).  &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;One of the other advantages of FIT is that a BA can “own” the generation of requirements and tests, since they are maintained in a single location.  A BA can easily design the test scenarios that the system must pass; I’ve seen complex requirements in Excel spreadsheets plenty of times, so I have no doubt about the ability of our BAs to generate FIT scenarios.  On the other hand, how many BAs could write a unit test?&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;Using FIT can help answer many project management questions:&lt;/font&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;&lt;em&gt;Developer:&lt;/em&gt; How have requirements for the system changed?  &lt;em&gt;Answer&lt;/em&gt;: check the FIT document.&lt;/font&gt; &lt;/li&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;&lt;em&gt;Developer&lt;/em&gt;: What are the requirements I should work on?  &lt;em&gt;Answer&lt;/em&gt;: see which FIT tests have not yet passed.&lt;/font&gt; &lt;/li&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;&lt;em&gt;BA&lt;/em&gt;: How close are we to completing the latest project milestone?  &lt;em&gt;Answer&lt;/em&gt;: run the FIT tests and see how many tests have not yet passed.&lt;/font&gt; &lt;/li&gt;
    &lt;li&gt;&lt;font face="Arial"&gt;&lt;em&gt;BA&lt;/em&gt;: Do the latest changes contain any regressions?  &lt;em&gt;Answer&lt;/em&gt;: run the FIT tests and see if any tests that used to pass have started to fail.&lt;/font&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;font face="Arial"&gt;It is true that the FIT tests do not run against the actual UI.  I see this is a positive, as it will prevent the project team from falling into the “&lt;a href="http://codeidol.com/csharp/domain-driven-design/Isolating-the-Domain/The-Smart-UI-Anti-Pattern/"&gt;Smart UI&lt;/a&gt;” trap.  However, it also means that FIT, however useful I think it will be, is not a silver bullet; testers will still have to interact with the system’s UI.   &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;Nevertheless, I think FIT will prove very helpful for this project, and for our shop in general.  And since BAs have to write requirements and perform testing, and developers have to translate requirements into testable code anyway, using FIT should not be burdensome.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;&lt;/font&gt; &lt;/p&gt; &lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/119320.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2008/02/05/119320.aspx</guid>
            <pubDate>Tue, 05 Feb 2008 22:12:48 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/119320.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2008/02/05/119320.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/119320.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/119320.aspx</trackback:ping>
        </item>
        <item>
            <title>A Tool for Troubleshooting Web Apps and Web Services</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2008/01/28/119004.aspx</link>
            <description>&lt;p&gt;Recently I discovered a tool that I had needed for a long time.  &lt;a href="http://www.fiddlertool.com/fiddler/"&gt;Fiddler&lt;/a&gt;, a freeware product created and supported by Microsoftie Eric Lawson, can be used to debug HTTP traffic from any web browser (or client application).  Here's how you can use it:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. View/Analyze HTTP traffic.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;One of our web apps creates a new window and performs a javascript-driven auto-logon to a vendor application.  When we reported an issue to the vendor, they started asking questions about whether we were using the correct version of their javascript module.  Rather than attempting to debug the javascript, I simply used Fiddler to capture all the HTTP traffic between my browser and the vendor's web server.  Fiddler formatted the data quite nicely, which made verifying my browser's behavior quite simple.  Fiddler was also able to save the relevant portions of the HTTP conversation to a log file, which I forwarded to the vendor.  The vendor was able to determine quickly that the error was in the behavior of their web server, rather than in any incorrect use of javascript on our part. &lt;/p&gt;
&lt;p&gt;Just one day later, another vendor questioned whether one of our web services was correctly returning error data.  Source code-level debugging in the web service would have done me no good, since I had to verify the data being transmitted on the wire.  But Fiddler made the investigation easy.  I used Fiddler to capture an interaction between a test client and the service, and quickly verified that our service was returning the correct error data. &lt;/p&gt;
&lt;p&gt;You can also use Fiddler to view all the details of a secure HTTP interaction.  Try doing that with netmon!  Just configure Fiddler to view HTTPS traffic, and it will hook any secure HTTP transactions.  It uses the "man-in-the-middle" strategy: it sets up a secure HTTP transaction between the browser and itself, then transmits the data it receives to the target URL over secure HTTP.  Sitting in the middle, it is able to view all the data in the browser-server conversation.  You just have to tell your browser to ignore the any certificate errors associated with the temporary certificate that Fiddler generates.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Generate test scripts.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Visual Studio 2005 Test Edition has a tool that allow you to generate a test script for a web app by capturing the interaction between a browser and a web app.  However, this tool only captures interactions (such as form submits) generated by clicking on links and buttons.  So how do you capture javascript-driven AJAX interactions?  Use Fiddler!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Analyze performance enhancements.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you are trying to figure out how various browser settings will affect a website's performance, Fiddler can help.  You can script Fiddler to intercept browser interactions and alter metadata, which allows you to perform a "what if" analysis on the fly.  And Fiddler has a built-in timer to measure wall clock time during the interaction. &lt;/p&gt;
&lt;p&gt;The Fiddler site has extensive documentation, including some &lt;a href="http://www.fiddlertool.com/Fiddler/help/video/default.asp"&gt;good QuickStart videos&lt;/a&gt;.  If you've been looking for a good tool to analyze HTTP traffic, look no more; go directly to the Fiddler &lt;a href="http://www.fiddlertool.com/fiddler/version.asp"&gt;download page&lt;/a&gt; and get started!&lt;/p&gt; &lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/119004.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2008/01/28/119004.aspx</guid>
            <pubDate>Mon, 28 Jan 2008 13:20:45 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/119004.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2008/01/28/119004.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/119004.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/119004.aspx</trackback:ping>
        </item>
        <item>
            <title>Test-Driven Design: Make Sure You Fail!</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2007/10/20/116190.aspx</link>
            <description>&lt;p&gt;The idea behind test-driven design (TDD) is to incorporate testing into the process of constructing your system, rather than waiting for developers to check in their code and to build a system that someone else tests.  TDD has some advantages worth considering:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Defects are identified sooner in the development process, which makes delivery of a reliable system cheaper and quicker. &lt;/li&gt;
    &lt;li&gt;Developers have more scope to improve the quality of code by refactoring, since they can run unit tests as they are making changes to verify whether the system still behaves as expected. &lt;/li&gt;
    &lt;li&gt;Unit tests serve as built-in documentation on how to call and make use of interfaces. &lt;/li&gt;
    &lt;li&gt;This built-in documentation is guaranteed not to go out of date.  (You've never had the joy of working with out-of-date documentation, have you?  You haven't &lt;em&gt;lived&lt;/em&gt; until you've debugged some code whose documentation does not match.  Or perhaps I should say, you haven't worked in software development unless you've debugged, etc.) &lt;/li&gt;
    &lt;li&gt;A team can run unit tests in the final step of the build process, in order to verify that the new build has no obvious defects. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The test-driven design process goes like this:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Get the requirement from the customer. &lt;/li&gt;
    &lt;li&gt;Design a test suite that will verify that the requirement is satisfied. &lt;/li&gt;
    &lt;li&gt;Run the test suite and make sure it fails. &lt;/li&gt;
    &lt;li&gt;Write code and run the test suite until it succeeds. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When the test suite succeeds and there are no obvious ways to simplify the code, the developer performs his customary victory dance and checks in the code.&lt;/p&gt;
&lt;p&gt;I have incorporated TDD into the development process for some web services that have multiple customers.  If we did not have a more or less complete suite of unit tests, any modification would be hard to manage.  &lt;em&gt;Any&lt;/em&gt; codepath that &lt;em&gt;any&lt;/em&gt; customer relies on could have a regression when any code is changed, right?  So in the absence of TDD, &lt;em&gt;any&lt;/em&gt; modification would require that several testers (Pat, Tammy, and Charles at our office) spend a fair amount of their precious time running regression tests.  Consequently, I have created suites of unit tests to verify that no regressions have occurred, and have even given them names ("virtual Pat," "virtual Tammy," and "virtual Charles") .  Virtual Pat and her virtual colleagues are working hard so that the real Pat and her colleagues can head home at 5pm.  &lt;/p&gt;
&lt;p&gt;Recently I received a requirement to modify a service method so that it would return extra data.  After I revised the unit tests, I almost skipped over step #3 (make sure the test fails).  After all, I was in a hurry, and why bother?  Aren't my coding skills good enough to write a simple test?&lt;/p&gt;
&lt;p&gt;Evidently not.  &lt;/p&gt;
&lt;p&gt;I ran the test suite and &lt;em&gt;it did not fail.&lt;/em&gt;  I rubbed my eyes in disbelief and ran the suite again; of course, it succeeded again.   A quick glance at the tests showed that the test suite contained the extra data expected from the method, but I had failed to write the assertions that would compare the expected data with the actual data returned from the method.  So if the actual data returned from the method was not correct, the test (and the developer) would never know it.  Doh! &amp;lt;Sound of hand smacking forehead /&amp;gt; &lt;/p&gt;
&lt;p&gt;So I added the assertions, ran the test suite (Hurrah!  It failed!), wrote the new code, ran the test suite again, and it succeeded.  I checked in my code, and it's working as expected.&lt;/p&gt;
&lt;p&gt;The moral of this tale is simple: in test-driven design, you have to fail before you can succeed.&lt;/p&gt; &lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/116190.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2007/10/20/116190.aspx</guid>
            <pubDate>Sat, 20 Oct 2007 18:39:53 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/116190.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2007/10/20/116190.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/116190.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/116190.aspx</trackback:ping>
        </item>
        <item>
            <title>How To: Write a Unit Test for Multi-Dimensioned Output</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2007/05/04/112254.aspx</link>
            <description>&lt;p&gt;One of the cool features of Visual Studio 2005 is that it can generate a unit test stub for a class or method.  However, I recently discovered that the Unit Test plug-in does not know how to auto-generate an assertion for a method whose output includes a multi-dimensioned out parameter or return value.  Here's the relevant stub code that VS 2005 generated for one of my methods whose output includes a multi-dimensioned array:&lt;/p&gt;
&lt;div class="code"&gt;
&lt;p&gt;&lt;font color="#008000" size="2"&gt;// generated code that creates a class instance called "target", plus other input + expected output parameters&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;font size="2"&gt;[][]&lt;/font&gt; homeAttributes;&lt;br /&gt;
&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;font size="2"&gt;[][]&lt;/font&gt; homeAttributes_expected = null; &lt;font color="#008000" size="2"&gt;// TODO: Initialize to an appropriate value&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;target.MethodBeingTested(in1, in2, &lt;font color="#0000ff"&gt;out&lt;/font&gt; homeAttributes)&lt;/font&gt;&lt;/p&gt;
&lt;font size="2"&gt;
&lt;p&gt;&lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual(homeAttributes_expected[i], homeAttributes[i], &lt;font color="#a31515" size="2"&gt;"homeAttributes was not set correctly."&lt;/font&gt;);&lt;/p&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;p&gt;&lt;font size="2"&gt;So I edited the code to initialize homeAttributes_expected, then ran the unit test, and it failed.  Okay, my code must have a bug...but when I reviewed the code for MethodBeingTested(), it sure looked right.  Then I stepped through the unit test in debug mode.  However, when I hit the breakpoint on &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() and expanded the arrays, the data was exactly what I expected it to be.  So maybe my initialization code for homeAttributes_expected was wrong...but no, it looked right.  What was wrong with this picture?&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;(These are the kind of challenges that either bring out the best or the worst in a software developer.  You either rise to the occasion, or become a broken, miserable, and somewhat sneaky creature that silently excises the &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() statement so the unit test will pass.  And I was not about to steal away quietly!)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;I realized what must be happening: &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() must be calling the object.Equals() method to compare each member of the collections.  And in a multi-dimensioned array, the collection object being tested (the array of arrays) consists of members that are themselves collections (i.e., arrays).  Since the built-in Array class in the .NET Framework does not override the object.Equals() method, &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() will use the default object.Equals() method to compare the &lt;em&gt;identity &lt;/em&gt;of the array members; in other words, it compares the address of the 2 arrays in memory.  These will of course be different, so the assertion fails, and the unit test fails.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;You have probably noticed that this post claims to apply to all multi-dimensioned output.  That's because you will encounter the same problem if your output is a &lt;font color="#2b91af" size="2"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&amp;gt;[], or a &lt;font color="#2b91af" size="2"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#2b91af" size="2"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&amp;gt;&amp;gt;, or any other multi-dimensioned object.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;Fortunately, you can conquer this problem with some clever refactoring.  Just iterate through the outer dimension, and call &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual on the inner collections.  Write your code like this, and everything will work just the way you want it to:&lt;/font&gt;&lt;/p&gt;
&lt;div class="code"&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#0000ff" size="2"&gt;for&lt;/font&gt;&lt;font size="2"&gt; (&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;int&lt;/font&gt; i = 0; i &amp;lt; homeAttributes_expected.GetLength(0); i++)&lt;br /&gt;
{&lt;br /&gt;
  &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual(homeAttributes_expected[i], homeAttributes[i], &lt;font color="#a31515" size="2"&gt;"MethodBeingTested_homeAttributes_expected was not set correctly at index "&lt;/font&gt; + i.ToString());&lt;br /&gt;
}&lt;/font&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() compares two single-dimensioned collections each time it is called.  As a result, when it calls object.Equals() on the members of the collections, it will use the member type's override of object.Equals()--in this case, String.Equals()--and the assertion works correctly.&lt;/p&gt;
&lt;p&gt;Happy unit testing!&lt;/p&gt; &lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/112254.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2007/05/04/112254.aspx</guid>
            <pubDate>Fri, 04 May 2007 13:42:42 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/112254.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2007/05/04/112254.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/112254.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/112254.aspx</trackback:ping>
        </item>
    </channel>
</rss>
