<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>// ThomasWeller</title>
        <link>http://geekswithblogs.net/thomasweller/Default.aspx</link>
        <description>C#/.NET software development, software integrity, life as a freelancer, and all the rest</description>
        <language>en-US</language>
        <copyright>Thomas Weller</copyright>
        <managingEditor>info@thomas-weller.de</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <image>
            <title>// ThomasWeller</title>
            <url>http://geekswithblogs.net/images/RSS2Image.gif</url>
            <link>http://geekswithblogs.net/thomasweller/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>Testing Entity Framework applications, pt. 3: NDbUnit</title>
            <category>Unit Testing/TDD</category>
            <category>Automation</category>
            <category>Open Source</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2011/11/10/testing-entity-framework-applications-pt.-3-ndbunit.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2011/11/10/testing-entity-framework-applications-pt.-3-ndbunit.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2011/11/10/testing-entity-framework-applications-pt.-3-ndbunit.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This is the third of a three part series that deals with the issue of faking test data in the context of a legacy app that was built with Microsoft's &lt;a href="http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework" target="_blank"&gt;Entity Framework&lt;/a&gt; (EF) on top of an &lt;a href="http://www.microsoft.com/sqlserver/en/us/default.aspx" target="_blank"&gt;MS SQL Server&lt;/a&gt; database – a scenario that can be found very often. Please read the &lt;a href="http://geekswithblogs.net/thomasweller/archive/2011/11/06/testing-entity-framework-applications-pt.-1.aspx" target="_blank"&gt;first part&lt;/a&gt; for a description of the sample application, a discussion of some general aspects of unit testing in a database context, and of some more specific aspects of the here discussed EF/MSSQL combination.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Lately, I wondered how you would ‘mock’ the data layer of a legacy application, when this data layer is made up of an &lt;a href="http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework"&gt;MS Entity Framework&lt;/a&gt; (EF) model in combination with a &lt;a href="http://www.microsoft.com/sqlserver/en/us/default.aspx"&gt;MS SQL Server&lt;/a&gt; database. Originally, this question came up in the context of how you could enable higher-level integration tests (automated UI tests, to be exact) for a legacy application that uses this EF/MSSQL combo as its data store mechanism – a not so uncommon scenario.&lt;/p&gt;
&lt;p&gt;The question sparked my interest, and I decided to dive into it somewhat deeper. What I've found out is, in short, that it's not very easy and straightforward to do it – but it can be done. The two strategies that are best suited to fit the bill involve using either the (commercial) &lt;a href="http://www.typemock.com/typemock-isolator-product3/"&gt;Typemock Isolator&lt;/a&gt; tool or the (free) &lt;a href="http://code.google.com/p/ndbunit/"&gt;NDbUnit&lt;/a&gt; framework. The use of Typemock was discussed in the &lt;a href="http://geekswithblogs.net/thomasweller/archive/2011/11/08/testing-entity-framework-applications-pt.-2-typemock.aspx" target="_blank"&gt;previous post&lt;/a&gt;, this post now will present the NDbUnit approach...&lt;/p&gt;
&lt;p&gt;NDbUnit is an Apache 2.0-licensed open-source project, and like so many other N&lt;em&gt;xxx&lt;/em&gt; tools and frameworks, it is basically a C#/.NET port of the corresponding Java version (&lt;a href="http://www.dbunit.org/" target="_blank"&gt;DbUnit&lt;/a&gt; namely). In short, it helps you in flexibly managing the state of a database in that it lets you easily perform basic operations (like e.g. &lt;em&gt;Insert, Delete, Refresh, DeleteAll&lt;/em&gt;)  against your database and, most notably, lets you feed it with data from external xml files.&lt;/p&gt;
&lt;p&gt;Let's have a look at how things can be done with the help of this framework.&lt;/p&gt;
&lt;h1&gt;Preparing the test data&lt;/h1&gt;
&lt;p&gt;Compared to Typemock, using NDbUnit implies a totally different approach to meet our testing needs.  So the here described testing scenario requires an instance of an SQL Server database in operation, and it also means that the Entity Framework model that sits on top of this database is completely unaffected.&lt;/p&gt;
&lt;p&gt;First things first: For its interactions with the database, NDbUnit relies on a .NET Dataset xsd file. See Step 1 of their &lt;a href="http://code.google.com/p/ndbunit/wiki/QuickStartGuide" target="_blank"&gt;Quick Start Guide&lt;/a&gt; for a description of how to create one. With this prerequisite in place then, the test fixture's setup code could look something like this:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 901px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;TestFixture&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;PersonRepository&lt;/span&gt;))]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Metadata&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"NDbUnit Quickstart URL"&lt;/span&gt;,     &lt;br /&gt;
          &lt;span style="color: #a31515"&gt;"http://code.google.com/p/ndbunit/wiki/QuickStartGuide"&lt;/span&gt;)]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Description&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Uses the NDbUnit library to provide test data to a local database."&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PersonRepositoryFixture&lt;/span&gt;     &lt;br /&gt;
{     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Constants     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; XmlSchema = &lt;span style="color: #a31515"&gt;@"..\..\TestData\School.xsd"&lt;/span&gt;;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #endregion&lt;/span&gt; &lt;span style="color: #008000"&gt;// Constants&lt;/span&gt;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Fields     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SchoolEntities&lt;/span&gt; _schoolContext;     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PersonRepository&lt;/span&gt; _personRepository;     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;INDbUnitTest&lt;/span&gt; _database;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #endregion&lt;/span&gt; &lt;span style="color: #008000"&gt;// Fields&lt;/span&gt;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Setup/TearDown     &lt;br /&gt;
&lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;FixtureSetUp&lt;/span&gt;]     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FixtureSetUp()     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; connectionString = &lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings[&lt;span style="color: #a31515"&gt;"School_Test"&lt;/span&gt;].ConnectionString;     &lt;br /&gt;
&lt;br /&gt;
        _database = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SqlDbUnitTest&lt;/span&gt;(connectionString);     &lt;br /&gt;
        _database.ReadXmlSchema(XmlSchema);     &lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; entityConnectionStringBuilder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EntityConnectionStringBuilder&lt;/span&gt;     &lt;br /&gt;
        {     &lt;br /&gt;
            Metadata = &lt;span style="color: #a31515"&gt;"res://*/School.csdl|res://*/School.ssdl|res://*/School.msl"&lt;/span&gt;,     &lt;br /&gt;
            Provider = &lt;span style="color: #a31515"&gt;"System.Data.SqlClient"&lt;/span&gt;,     &lt;br /&gt;
            ProviderConnectionString = connectionString     &lt;br /&gt;
        };     &lt;br /&gt;
&lt;br /&gt;
        _schoolContext = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SchoolEntities&lt;/span&gt;(entityConnectionStringBuilder.ConnectionString);     &lt;br /&gt;
        _personRepository = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PersonRepository&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._schoolContext);     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;FixtureTearDown&lt;/span&gt;]     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FixtureTearDown()     &lt;br /&gt;
    {     &lt;br /&gt;
        _database.PerformDbOperation(&lt;span style="color: #2b91af"&gt;DbOperationFlag&lt;/span&gt;.DeleteAll);     &lt;br /&gt;
        _schoolContext.Dispose();     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    ...&lt;/div&gt;
&lt;p&gt; As you can see, there is slightly more fixture setup code involved if your tests are using NDbUnit to provide the test data: Because we're dealing with a physical database instance here, we first need to pick up the test-specific connection string from the test assemblies' &lt;font face="Courier New"&gt;App.config&lt;/font&gt;, then initialize an NDbUnit helper object with this connection along with the provided xsd file, and also set up the &lt;font face="Courier New"&gt;SchoolEntities&lt;/font&gt; and the &lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt; instances accordingly.&lt;/p&gt;
&lt;p&gt;The _&lt;font face="Courier New"&gt;database&lt;/font&gt; field (an instance of the &lt;font face="Courier New"&gt;INdUnitTest&lt;/font&gt; interface) will be our single access point to the underlying database: We use it to perform all the required operations against the data store. To have a flexible mechanism to easily insert data into the database, we can write a helper method like this:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 505px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; InsertTestData(&lt;span style="color: #0000ff"&gt;params&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] dataFileNames)     &lt;br /&gt;
{     &lt;br /&gt;
    _database.PerformDbOperation(&lt;span style="color: #2b91af"&gt;DbOperationFlag&lt;/span&gt;.DeleteAll);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (dataFileNames == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; fileName &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dataFileNames)     &lt;br /&gt;
        {     &lt;br /&gt;
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #2b91af"&gt;File&lt;/span&gt;.Exists(fileName))     &lt;br /&gt;
            {     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;FileNotFoundException&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;.GetFullPath(fileName));     &lt;br /&gt;
            }     &lt;br /&gt;
            _database.ReadXml(fileName);     &lt;br /&gt;
            _database.PerformDbOperation(&lt;span style="color: #2b91af"&gt;DbOperationFlag&lt;/span&gt;.InsertIdentity);     &lt;br /&gt;
        }     &lt;br /&gt;
    }     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt;     &lt;br /&gt;
    {     &lt;br /&gt;
        _database.PerformDbOperation(&lt;span style="color: #2b91af"&gt;DbOperationFlag&lt;/span&gt;.DeleteAll);     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;;     &lt;br /&gt;
    }     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;This lets us easily insert test data from xml files, in any number and in a  controlled order (which is important because we eventually must fulfill referential constraints, or we must account for some other stuff that imposes a specific ordering on data insertion). Again, as with Typemock, I won't go into API details here. - Unfortunately, there isn't too much documentation for NDbUnit anyway, other than the already mentioned Quick Start Guide (and the source code itself, of course) - a not so uncommon problem with smaller Open Source Projects.&lt;/p&gt;
&lt;p&gt;Last not least, we need to provide the required test data in xml form. A snippet for data from the &lt;font face="Courier New"&gt;People&lt;/font&gt; table might look like this, for example:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 289px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515"&gt;xml&lt;/span&gt;&lt;span style="color: #0000ff"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&lt;/span&gt;"&lt;span style="color: #0000ff"&gt;1.0&lt;/span&gt;"&lt;span style="color: #0000ff"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;encoding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&lt;/span&gt;"&lt;span style="color: #0000ff"&gt;utf-8&lt;/span&gt;"&lt;span style="color: #0000ff"&gt; ?&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;School&lt;/span&gt;&lt;span style="color: #0000ff"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&lt;/span&gt;"&lt;span style="color: #0000ff"&gt;http://tempuri.org/School.xsd&lt;/span&gt;"&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Person&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PersonID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PersonID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LastName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Abercrombie&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;LastName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;FirstName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Kim&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;FirstName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;HireDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1995-03-11T00:00:00&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;HireDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Person&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Person&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PersonID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PersonID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LastName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Barzdukas&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;LastName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;FirstName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Gytis&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;FirstName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;EnrollmentDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;2005-09-01T00:00:00&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;EnrollmentDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Person&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Person&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;     &lt;br /&gt;
    ...&lt;/div&gt;
&lt;p&gt;You can also have data from various tables in one single xml file, if that's appropriate for you (but beware of the already mentioned ordering issues). It's true that your test assembly may end up with dozens of such xml files, each containing quite a big amount of text data. But because the files are of very low complexity, and with the help of a little bit of Copy/Paste and Excel magic, this appears to be well manageable.&lt;/p&gt;
&lt;h1&gt;Executing some basic tests&lt;/h1&gt;
&lt;p&gt;Here are some of the possible tests that can be written with the above preparations in place:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 559px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; People = &lt;span style="color: #a31515"&gt;@"..\..\TestData\School.People.xml"&lt;/span&gt;;     &lt;br /&gt;
&lt;br /&gt;
...     &lt;br /&gt;
&lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetNameList"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetNameList_ListOrdering_ReturnsTheExpectedFullNames()     &lt;br /&gt;
{     &lt;br /&gt;
    InsertTestData(People);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; names =     &lt;br /&gt;
        _personRepository.GetNameList(&lt;span style="color: #2b91af"&gt;NameOrdering&lt;/span&gt;.List);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Count(34, names);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Abercrombie, Kim"&lt;/span&gt;, names.First());     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Zheng, Roger"&lt;/span&gt;, names.Last());     &lt;br /&gt;
}     &lt;br /&gt;
&lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetNameList"&lt;/span&gt;)]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;DependsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"RemovePerson_CalledOnce_DecreasesCountByOne"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetNameList_NormalOrdering_ReturnsTheExpectedFullNames()     &lt;br /&gt;
{     &lt;br /&gt;
    InsertTestData(People);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; names =     &lt;br /&gt;
        _personRepository.GetNameList(&lt;span style="color: #2b91af"&gt;NameOrdering&lt;/span&gt;.Normal);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Count(34, names);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Alexandra Walker"&lt;/span&gt;, names.First());     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Yan Li"&lt;/span&gt;, names.Last());     &lt;br /&gt;
}     &lt;br /&gt;
&lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.AddPerson"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddPerson_CalledOnce_IncreasesCountByOne()     &lt;br /&gt;
{     &lt;br /&gt;
    InsertTestData(People);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; count = _personRepository.Count;     &lt;br /&gt;
&lt;br /&gt;
    _personRepository.AddPerson(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; { FirstName = &lt;span style="color: #a31515"&gt;"Thomas"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Weller"&lt;/span&gt; });     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(count + 1, _personRepository.Count);     &lt;br /&gt;
}     &lt;br /&gt;
&lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.RemovePerson"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RemovePerson_CalledOnce_DecreasesCountByOne()     &lt;br /&gt;
{     &lt;br /&gt;
    InsertTestData(People);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; count = _personRepository.Count;     &lt;br /&gt;
&lt;br /&gt;
    _personRepository.RemovePerson(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; { PersonID = 33 });     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(count - 1, _personRepository.Count);     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;Not much difference here compared to the &lt;a href="http://geekswithblogs.net/thomasweller/archive/2011/11/08/testing-entity-framework-applications-pt.-2-typemock.aspx#BasicTests" target="_blank"&gt;corresponding Typemock versions&lt;/a&gt;, except that we had to do a bit more preparational work (and also it was harder to get the required knowledge). But this picture changes quite dramatically if we look at some more demanding test cases:&lt;/p&gt;
&lt;h1&gt;Ok, and what if things are becoming somewhat more complex?&lt;/h1&gt;
&lt;p&gt;Tests like the above ones represent the 'easy' scenarios. They may account for the biggest portion of real-world use cases of the application, and they are important to make sure that it is generally sound. But usually, all these nasty little bugs originate from the more complex parts of our code, or they occur when something goes wrong.&lt;/p&gt;
&lt;p&gt;So, for a testing strategy to be of real practical use, it is especially important to see how easy or difficult it is to mimick a scenario which represents a more complex or exceptional case. The following test, for example, deals with the case that there is some sort of invalid input from the caller:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 198px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetCourseMembers"&lt;/span&gt;)]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;))]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(&lt;span style="color: #a31515"&gt;""&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;))]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"NotExistingCourse"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;))]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetCourseMembers_WithGivenVariousInvalidValues_Throws(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; courseTitle, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; expectedInnerExceptionType)     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; exception = &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Throws&amp;lt;&lt;span style="color: #2b91af"&gt;RepositoryException&lt;/span&gt;&amp;gt;(() =&amp;gt;     &lt;br /&gt;
                                _personRepository.GetCourseMembers(courseTitle));     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsInstanceOfType(expectedInnerExceptionType, exception.InnerException);     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;&lt;font color="#e7e7e7"&gt;Apparently, this test doesn't need an 'Arrange' part at all (see &lt;a href="http://geekswithblogs.net/thomasweller/archive/2011/11/08/testing-entity-framework-applications-pt.-2-typemock.aspx#MoreComplexTest" target="_blank"&gt;here&lt;/a&gt; for the same test with the Typemock tool). It acts just like any other client code, and all the required business logic comes from the database itself. This doesn't always necessarily mean that there is less complexity, but only that the complexity happens in a different part of your test resources (in the xml files namely, where you sometimes have to spend a lot of effort for carefully preparing the required test data). &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#e7e7e7"&gt;Another example, which relies on an underlying 1-n relationship, might be this:&lt;/font&gt;&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 262px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetCourseMembers"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetCourseMembers_WhenGivenAnExistingCourse_ReturnsListOfStudents()     &lt;br /&gt;
{     &lt;br /&gt;
    InsertTestData(People, Course, Department, StudentGrade);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt; persons = _personRepository.GetCourseMembers(&lt;span style="color: #a31515"&gt;"Macroeconomics"&lt;/span&gt;);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Count(4, persons);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.ForAll(     &lt;br /&gt;
        persons,     &lt;br /&gt;
        @p =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;[] { 10, 11, 12, 14 }.Contains(@p.PersonID),     &lt;br /&gt;
        &lt;span style="color: #a31515"&gt;"Person has none of the expected IDs."&lt;/span&gt;);     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;If you compare this test to its &lt;a href="http://geekswithblogs.net/thomasweller/archive/2011/11/08/testing-entity-framework-applications-pt.-2-typemock.aspx#MoreComplexTest2" target="_blank"&gt;corresponding Typemock version&lt;/a&gt;, you immediately see that the test itself is much simpler, easier to read, and thus much more intention-revealing. The complexity here lies hidden behind the call to the &lt;font face="Courier New"&gt;InsertTestData()&lt;/font&gt; helper method and the content of the used xml files with the test data. And also note that you might have to provide additional data which are not even directly relevant to your test, but are required only to fulfill some integrity needs of the underlying database.&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;The first thing to notice when comparing the NDbUnit approach to its Typemock counterpart obviously deals with performance: Of course, NDbUnit is much slower than Typemock. Technically,  it doesn't even make sense to compare the two tools. But practically, it may well play a role and could or could not be an issue, depending on how much tests you have of this kind, how often you run them, and what role they play in your development cycle.&lt;/p&gt;
&lt;p&gt;Also, because the dataset from the required xsd file must &lt;em&gt;fully&lt;/em&gt; match the database schema (even in parts that otherwise wouldn't be relevant to you), it can be quite cumbersome to be in a team where different people are working with the database in parallel.&lt;/p&gt;
&lt;p&gt;My personal experience is – as already said in the &lt;a href="http://geekswithblogs.net/thomasweller/archive/2011/11/06/testing-entity-framework-applications-pt.-1.aspx" target="_blank"&gt;first part&lt;/a&gt; – that Typemock gives you a better development experience in a 'dynamic' scenario (when you're working in some kind of TDD-style, you're oftentimes executing the tests from your dev box, and your database schema changes frequently), whereas the NDbUnit approach is a good and solid solution in more 'static' development scenarios (when you need to execute the tests less frequently or only on a separate build server, and/or the underlying database schema can be kept relatively stable), for example some variations of higher-level integration or User-Acceptance tests.&lt;/p&gt;
&lt;p&gt;But in any case, opening Entity Framework based applications for testing requires a fair amount of resources, planning, and preparational work – it's definitely not the kind of stuff that you would call 'easy to test'. Hopefully, future versions of EF will take testing concerns into account. Otherwise, I don't see too much of a future for the framework in the long run, even though it's quite popular at the moment...&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;The sample solution&lt;/h1&gt;
&lt;p&gt;A sample solution (VS 2010) with the code from this article series is available via &lt;a href="https://bitbucket.org/thomas.weller" target="_blank"&gt;my Bitbucket account&lt;/a&gt; from &lt;a href="https://bitbucket.org/thomas.weller/testingentityframeworkapplications/overview" target="_blank"&gt;here&lt;/a&gt; (Bitbucket is a hosting site for &lt;a href="http://mercurial.selenic.com/" target="_blank"&gt;Mercurial&lt;/a&gt; repositories. The repositories may also be accessed with the &lt;a href="http://git-scm.com/" target="_blank"&gt;Git&lt;/a&gt; and &lt;a href="http://subversion.apache.org/" target="_blank"&gt;Subversion&lt;/a&gt; SCMs - consult the documentation for details. In addition, it is possible to download the solution simply as a zipped archive – via the 'get source' button on the very right.). The solution contains some more tests against the &lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt; class, which are not shown here. Also, it contains database scripts to create and fill the &lt;font face="Courier New"&gt;School&lt;/font&gt; sample database.&lt;/p&gt;
&lt;p&gt;To compile and run, the solution expects the Gallio/MbUnit framework to be installed (which is free and can be downloaded from &lt;a href="http://www.gallio.org/Downloads.aspx" target="_blank"&gt;here&lt;/a&gt;), the NDbUnit framework (which is also free and can be downloaded from &lt;a href="http://code.google.com/p/ndbunit/downloads/list" target="_blank"&gt;here&lt;/a&gt;), and the Typemock Isolator tool (a fully functional 30day-trial is available &lt;a href="http://www.typemock.com/download/" target="_blank"&gt;here&lt;/a&gt;). Moreover, you will need an instance of the Microsoft SQL Server DBMS, and you will have to adapt the connection strings in the test projects &lt;font face="Courier New"&gt;App.config&lt;/font&gt; files accordingly.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table width="580" cellspacing="2" cellpadding="6" border="0" style="background-image: url(http://gwb.blob.core.windows.net/thomasweller/social/pictures/socialb-580x100.gif); background-repeat: no-repeat; background-position: -5px 50%"&gt;
    &lt;tbody&gt;
        &lt;tr style="padding-top: 4px"&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="kickit"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url="&gt;&lt;img width="88" border="0" height="22" style="position: relative; display: inline; cursor: pointer; padding-top: 6px; top: 4px" id="kick" title="Kick it!" alt="kickit" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="shoutit"&gt;&lt;a href="http://dotnetshoutout.com/Submit?url="&gt;&lt;img border="0" style="position: relative; display: inline; cursor: pointer; padding-top: 6px; top: 4px" id="shout" title="Shout it!" alt="shoutit" src="http://dotnetshoutout.com/image.axd?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="330" valign="middle" align="left"&gt;
            &lt;div id="zoneit"&gt;&lt;iframe width="150" height="20" frameborder="0" scrolling="no" style="position: relative; top: 4px" id="dzoneframe" title="Zone it!" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&amp;amp;url=&amp;amp;title="&gt;&lt;/iframe&gt;&lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="middle" colspan="3"&gt;&lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="delicious" title="Bookmark this on Delicious." onclick="setBookmark('delicious');" alt="delicious" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/delicious-32x32.png" /&gt; &lt;a id="fbshare" href="http://www.facebook.com/sharer.php"&gt;&lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; left: 2px" id="facebook" title="Share this on Facebook." alt="facebook" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/facebook-48x48.png" /&gt;&lt;/a&gt; &lt;img width="34" border="0" height="34" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="digg" title="Digg this." onclick="setBookmark('digg');" alt="digg" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/digg-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="reddit" title="Reddit this." onclick="setBookmark('reddit');" alt="reddit" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/reddit-48x48.png" /&gt; &lt;img width="34" border="0" height="34" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="linkedin" title="Share this on LinkedIn." onclick="setBookmark('linkedin');" alt="linkedin" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/linkedin-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="stumbleupon" title="Stumble!" onclick="setBookmark('stumbleupon');" alt="stumbleupon" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/stumbleupon-48x48.png" /&gt; &lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; padding-top: 1px; left: 2px" id="technorati" title="Add this to Technorati." onclick="setBookmark('technorati')" alt="technorati" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/technorati-48x48.png" /&gt; &lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; margin: 1px 0px 0px 1px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="mrwong" title="Bookmark this on Mister Wong." onclick="setBookmark('mrwong');" alt="mrwong" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/mrwong-32x32.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="yahoobkm" title="Bookmark this on Yahoo." onclick="setBookmark('yahoobkm')" alt="yahoo" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/yahoo-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="googlebkm" title="Bookmark this on Google." onclick="setBookmark('googlebkm');" alt="google-48x48" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/google-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="twitter" title="Tweet this (with bit.ly URL)." onclick="BitlyClient.shorten(document.location, 'BitlyCB.shortenResponse');" alt="twitter" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/twitter-48x48.png" /&gt; &lt;img width="31" border="0" height="31" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="mail" title="Send a link via E-Mail." onclick="mailpage();" alt="email" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/email-32x32.png" /&gt; &lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="bookmark" title="Bookmark this page in your browser." onclick="bookmarkInBrowser();" alt="favorites" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/favorites-star-128x128.png" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/147643.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2011/11/10/testing-entity-framework-applications-pt.-3-ndbunit.aspx</guid>
            <pubDate>Thu, 10 Nov 2011 06:36:54 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/147643.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2011/11/10/testing-entity-framework-applications-pt.-3-ndbunit.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/147643.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Testing Entity Framework applications, pt. 2: Typemock</title>
            <category>Unit Testing/TDD</category>
            <category>Automation</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2011/11/08/testing-entity-framework-applications-pt.-2-typemock.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2011/11/08/testing-entity-framework-applications-pt.-2-typemock.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2011/11/08/testing-entity-framework-applications-pt.-2-typemock.aspx&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;
&lt;p align="justify"&gt;This is the second of a three part series that deals with the issue of faking test data in the context of a legacy app that was built with Microsoft's &lt;a target="_blank" href="http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework"&gt;Entity Framework&lt;/a&gt; (EF) on top of an &lt;a target="_blank" href="http://www.microsoft.com/sqlserver/en/us/default.aspx"&gt;MS SQL Server&lt;/a&gt; database – a scenario that can be found very often. Please read the &lt;a target="_blank" href="http://geekswithblogs.net/thomasweller/archive/2011/11/06/testing-entity-framework-applications-pt.-1.aspx"&gt;first part&lt;/a&gt; for a description of the sample application, a discussion of some general aspects of unit testing in a database context, and of some more specific aspects of the here discussed EF/MSSQL combination.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Lately, I wondered how you would ‘mock’ the data layer of a legacy application, when this data layer is made up of an &lt;a target="_blank" href="http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework"&gt;MS Entity Framework&lt;/a&gt; (EF) model in team with a &lt;a target="_blank" href="http://www.microsoft.com/sqlserver/en/us/default.aspx"&gt;MS SQL Server&lt;/a&gt; database. The question originally came up in the context of how you could enable higher-level integration tests (automated UI tests, to be exact) for a legacy application that uses this EF/MSSQL combo as its data store mechanism – a not so uncommon scenario.&lt;/p&gt;
&lt;p&gt;The question sparked my interest, so I decided to dive into it a bit deeper. What I've found out is, in short, that it's not very easy and straightforward to do it – but it can be done. The two strategies that are best suited to fit the bill involve using either the (commercial) &lt;a target="_blank" href="http://www.typemock.com/typemock-isolator-product3/"&gt;Typemock Isolator&lt;/a&gt; tool or the (free) &lt;a target="_blank" href="http://code.google.com/p/ndbunit/"&gt;NDbUnit&lt;/a&gt; framework. This post will present the Typemock approach...&lt;/p&gt;
&lt;p&gt;When it comes to mocking and faking, Typemock is something like the swiss army knife in a tester's toolbelt. It's functionally comparable to &lt;a target="_blank" href="http://research.microsoft.com/en-us/projects/moles"&gt;MS Moles&lt;/a&gt;, in that there aren't any limits in what it can do (it's really &lt;a target="_blank" href="http://geekswithblogs.net/thomasweller/archive/2010/04/28/mocking-the-unmockable-using-microsoft-moles-with-gallio.aspx"&gt;Mocking the Unmockable&lt;/a&gt;). You can easily write all kinds of test doubles for components that you otherwise could not fake: Static classes, Framework classes, Sealed classes, Non-virtual members and so on... The big difference to Moles however is that Typemock has a well-crafted API and generally is so much easier to handle, understand, learn, and remember that this alone would justify the price difference.&lt;/p&gt;
&lt;h1&gt;Preparing the test data&lt;/h1&gt;
&lt;p&gt;As I have shown in the first part, the &lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt; expects an instance of EF's &lt;font face="Courier New"&gt;&lt;a target="_blank" href="http://www.google.de/url?sa=t&amp;amp;rct=j&amp;amp;q=objectcontext%20%20msdn&amp;amp;source=web&amp;amp;cd=2&amp;amp;ved=0CCYQFjAB&amp;amp;url=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fsystem.data.objects.objectcontext.aspx&amp;amp;ei=bSeyTpuTEJHCswbztJEm&amp;amp;usg=AFQjCNH9ezUv7Xs-4xVNDKflfE4WOoKFYA&amp;amp;sig2=RXjdO_zgjAZft7_nV0UnTQ&amp;amp;cad=rja"&gt;ObjectContext&lt;/a&gt;&lt;/font&gt; class in its c'tor. This project-specific class is generated by the EF designer and contains, among (too) many other things, the conceptual entity model which is derived from the underlying database. (It's called &lt;font face="Courier New"&gt;SchoolEntities&lt;/font&gt; in our case.)&lt;/p&gt;
&lt;p&gt;This marks the point where we can plug in the Typemock Isolator tool to isolate the system from the underlying database, faking the &lt;font face="Courier New"&gt;ObjectContext&lt;/font&gt; and thus having the opportunity to feed the &lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt; class with self-provided data on a per-test basis as required.&lt;/p&gt;
&lt;p&gt;The test fixture's Setup code will look like this, when using this approach:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 413px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;TestFixture&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;PersonRepository&lt;/span&gt;))]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Description&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Uses Typemock Isolator 2010 to fake the data for the applications EF data model. "&lt;/span&gt; +     &lt;br /&gt;
             &lt;span style="color: #a31515"&gt;"Trial version can be downloaded from here: http://www.typemock.com/typemock-isolator-product3/"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PersonRepositoryFixture&lt;/span&gt;     &lt;br /&gt;
{     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Fields     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SchoolEntities&lt;/span&gt; _schoolContext;     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PersonRepository&lt;/span&gt; _personRepository;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #endregion&lt;/span&gt; &lt;span style="color: #008000"&gt;// Fields&lt;/span&gt;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Setup/TearDown     &lt;br /&gt;
&lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;SetUp&lt;/span&gt;]     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SetUp()     &lt;br /&gt;
    {     &lt;br /&gt;
        _schoolContext = &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.Fake.Instance&amp;lt;&lt;span style="color: #2b91af"&gt;SchoolEntities&lt;/span&gt;&amp;gt;();     &lt;br /&gt;
        _personRepository = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PersonRepository&lt;/span&gt;(_schoolContext);     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    ...&lt;/div&gt;
&lt;p&gt;Note that we've altered only one single line of code here, compared to the 'original' version from the previous part: The _&lt;font face="Courier New"&gt;schoolContext&lt;/font&gt; field is initialized with a &lt;em&gt;Fake instance&lt;/em&gt; of the &lt;font face="Courier New"&gt;SchoolEntities&lt;/font&gt; class instead of the 'real' object (see &lt;a target="_blank" href="http://stackoverflow.com/questions/4001101/are-fakes-better-than-mocks/4002552#4002552"&gt;here&lt;/a&gt; for a short clarification of the sometimes confusing terminology around &lt;em&gt;mocks, fakes, stubs&lt;/em&gt; and the like).&lt;/p&gt;
&lt;p&gt;What does it mean? Well, it means that our _&lt;font face="Courier New"&gt;schoolContext&lt;/font&gt; field actually references a true instance of the &lt;font face="Courier New"&gt;SchoolEntities&lt;/font&gt; class, and not some sort of proxy object. You can call all methods and properties on it, they will do nothing by default and will return the respective default value for value types, or another &lt;em&gt;Fake instance&lt;/em&gt; for reference types - unless we explicitely tell Typemock to return some custom, pre-defined values for us (or call some custom code on our behalf). And that's exactly what we need here to isolate the system under test from its EF data model (and its database, consequently).&lt;/p&gt;
&lt;p&gt;To accomplish this, we first define a helper class to hold the test data that we will use (and also mimick other required database properties like e.g. referential constraints). It will act as a kind of 'in-memory database':&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 760px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;FakeDataHolder&lt;/span&gt;     &lt;br /&gt;
{     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Fields     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #008000"&gt;// The xxxData collections serve as an internal cache. They represent the database,&lt;/span&gt;     &lt;br /&gt;
    &lt;span style="color: #008000"&gt;// are filled during construction  and not altered thereafter.&lt;/span&gt;     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static readonly&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ReadOnlyCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt; PersonData;     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static readonly&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ReadOnlyCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;OfficeAssignment&lt;/span&gt;&amp;gt; OfficeAssignmentData;     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #008000"&gt;// The xxxList collections mirror the xxxData collections. They represent a working copy of the data,&lt;/span&gt;     &lt;br /&gt;
    &lt;span style="color: #008000"&gt;// which is exposed through properties to the outside and can be reset via the 'Reset()' method.&lt;/span&gt;     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt; PersonList = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt;();     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;OfficeAssignment&lt;/span&gt;&amp;gt; OfficeAssignmentList = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;OfficeAssignment&lt;/span&gt;&amp;gt;();     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #endregion&lt;/span&gt; &lt;span style="color: #008000"&gt;// Fields&lt;/span&gt;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Properties     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt; Persons     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; PersonList.AsQueryable(); }     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;OfficeAssignment&lt;/span&gt;&amp;gt; OfficeAssignments     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; OfficeAssignmentList.AsQueryable(); }     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #endregion&lt;/span&gt; &lt;span style="color: #008000"&gt;// Properties&lt;/span&gt;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Construction     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; FakeDataHolder()     &lt;br /&gt;
    {  &lt;br /&gt;
        PersonData = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt;     &lt;br /&gt;
            {     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 1, FirstName = &lt;span style="color: #a31515"&gt;"Kim"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Abercrombie"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 2, FirstName = &lt;span style="color: #a31515"&gt;"Gytis"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Barzdukas"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 3, FirstName = &lt;span style="color: #a31515"&gt;"Peggy"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Justice"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 4, FirstName = &lt;span style="color: #a31515"&gt;"Fadi"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Fakhouri"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 5, FirstName = &lt;span style="color: #a31515"&gt;"Roger"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Harui"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 6, FirstName = &lt;span style="color: #a31515"&gt;"Yan"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Li"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 7, FirstName = &lt;span style="color: #a31515"&gt;"Laura"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Norman"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 8, FirstName = &lt;span style="color: #a31515"&gt;"Nino"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Olivotto"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 9, FirstName = &lt;span style="color: #a31515"&gt;"Wayne"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Tang"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 10, FirstName = &lt;span style="color: #a31515"&gt;"Meredith"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Alonso"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 11, FirstName = &lt;span style="color: #a31515"&gt;"Sophia"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Lopez"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 12, FirstName = &lt;span style="color: #a31515"&gt;"Meredith"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Browning"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 13, FirstName = &lt;span style="color: #a31515"&gt;"Arturo"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Anand"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 14, FirstName = &lt;span style="color: #a31515"&gt;"Alexandra"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Walker"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 15, FirstName = &lt;span style="color: #a31515"&gt;"Carson"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Powell"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 16, FirstName = &lt;span style="color: #a31515"&gt;"Damien"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Jai"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 17, FirstName = &lt;span style="color: #a31515"&gt;"Robyn"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Carlson"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 18, FirstName = &lt;span style="color: #a31515"&gt;"Roger"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Zheng"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 19, FirstName = &lt;span style="color: #a31515"&gt;"Carson"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Bryant"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 20, FirstName = &lt;span style="color: #a31515"&gt;"Robyn"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Suarez"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 21, FirstName = &lt;span style="color: #a31515"&gt;"Roger"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Holt"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 22, FirstName = &lt;span style="color: #a31515"&gt;"Carson"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Alexander"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 23, FirstName = &lt;span style="color: #a31515"&gt;"Isaiah"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Morgan"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 24, FirstName = &lt;span style="color: #a31515"&gt;"Randall"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Martin"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 25, FirstName = &lt;span style="color: #a31515"&gt;"Candace"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Kapoor"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 26, FirstName = &lt;span style="color: #a31515"&gt;"Cody"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Rogers"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 27, FirstName = &lt;span style="color: #a31515"&gt;"Stacy"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Serrano"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 28, FirstName = &lt;span style="color: #a31515"&gt;"Anthony"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"White"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 29, FirstName = &lt;span style="color: #a31515"&gt;"Rachel"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Griffin"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 30, FirstName = &lt;span style="color: #a31515"&gt;"Alicia"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Shan"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 31, FirstName = &lt;span style="color: #a31515"&gt;"Jasmine"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Stewart"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 32, FirstName = &lt;span style="color: #a31515"&gt;"Kristen"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Xu"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 33, FirstName = &lt;span style="color: #a31515"&gt;"Erica"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Gao"}&lt;/span&gt;,     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 34, FirstName = &lt;span style="color: #a31515"&gt;"Roger"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Van Houten"}&lt;/span&gt;     &lt;br /&gt;
            }     &lt;br /&gt;
            .AsReadOnly();  &lt;br /&gt;
&lt;br /&gt;
        OfficeAssignmentData = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;OfficeAssignment&lt;/span&gt;&amp;gt;     &lt;br /&gt;
            {     &lt;br /&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;OfficeAssignment&lt;/span&gt; { InstructorID = 18, Location = &lt;span style="color: #a31515"&gt;"143 Smith"&lt;/span&gt; }     &lt;br /&gt;
            }     &lt;br /&gt;
            .AsReadOnly();     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #endregion&lt;/span&gt; &lt;span style="color: #008000"&gt;// Construction&lt;/span&gt;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Operations     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Reset()     &lt;br /&gt;
    {     &lt;br /&gt;
        PersonList.Clear();     &lt;br /&gt;
        PersonList.AddRange(PersonData);     &lt;br /&gt;
&lt;br /&gt;
        OfficeAssignmentList.Clear();     &lt;br /&gt;
        OfficeAssignmentList.AddRange(OfficeAssignmentData);     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddPerson(&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; person)     &lt;br /&gt;
    {     &lt;br /&gt;
        PersonList.Add(person);     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DeletePerson(&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; person)     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (OfficeAssignmentList.Any(@a =&amp;gt; @a.InstructorID == person.PersonID))     &lt;br /&gt;
        {     &lt;br /&gt;
            &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"FK_OfficeAssignment_Person"&lt;/span&gt;);     &lt;br /&gt;
        }     &lt;br /&gt;
&lt;br /&gt;
        PersonList.Remove(person);     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #endregion&lt;/span&gt; &lt;span style="color: #008000"&gt;// Operations&lt;/span&gt;     &lt;br /&gt;
&lt;br /&gt;
} &lt;span style="color: #008000"&gt;// class FakedataHolder&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;The second step then would be to make our test fixture's _&lt;font face="Courier New"&gt;schoolContext&lt;/font&gt; field return these values (or call the appropriate &lt;font face="Courier New"&gt;FakeDataHolder&lt;/font&gt; methods, respectively). For this purpose, we can declare a helper method like this in the &lt;font face="Courier New"&gt;PersonRepositoryFixture&lt;/font&gt; class:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 215px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FakeData()     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;FakeDataHolder&lt;/span&gt;.Reset();  &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; _schoolContext.People)  &lt;br /&gt;
           .WillReturnCollectionValuesOf(&lt;span style="color: #2b91af"&gt;FakeDataHolder&lt;/span&gt;.Persons);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; _schoolContext.People.AddObject(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;))     &lt;br /&gt;
           .DoInstead(@ctx =&amp;gt; &lt;span style="color: #2b91af"&gt;FakeDataHolder&lt;/span&gt;.AddPerson(@ctx.Parameters[0] &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;));     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; _schoolContext.People.DeleteObject(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;))     &lt;br /&gt;
           .DoInstead(@ctx =&amp;gt; &lt;span style="color: #2b91af"&gt;FakeDataHolder&lt;/span&gt;.DeletePerson(@ctx.Parameters[0] &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;));     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;I won't go into the details of Typemock's API syntax here (you may consult the &lt;a target="_blank" href="http://docs.typemock.com/Isolator/##typemock.chm/Documentation/Welcome.htm"&gt;Online Documentation&lt;/a&gt; for this, if you are interested), but generally I like it because it's very easy to read and understand without oversimplifying things. Or, in other words: I don't have to explain much here, the code itself tells it all...&lt;/p&gt;
&lt;h1&gt;Executing some basic tests&lt;/h1&gt;
&lt;p&gt;Here are some of the possible tests that can be written with the above preparations in place:&lt;/p&gt;
&lt;p&gt;&lt;a name="BasicTests"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 677px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Isolated&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetNameList"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetNameList_ListOrdering_ReturnsTheExpectedFullNames()     &lt;br /&gt;
{     &lt;br /&gt;
    FakeData();     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; names =     &lt;br /&gt;
        _personRepository.GetNameList(&lt;span style="color: #2b91af"&gt;NameOrdering&lt;/span&gt;.List);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Count(34, names);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Abercrombie, Kim"&lt;/span&gt;, names.First());     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Zheng, Roger"&lt;/span&gt;, names.Last());     &lt;br /&gt;
}     &lt;br /&gt;
&lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetNameList"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetNameList_NormalOrdering_ReturnsTheExpectedFullNames()     &lt;br /&gt;
{     &lt;br /&gt;
    FakeData();     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; names =     &lt;br /&gt;
        _personRepository.GetNameList(&lt;span style="color: #2b91af"&gt;NameOrdering&lt;/span&gt;.Normal);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Count(34, names);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Alexandra Walker"&lt;/span&gt;, names.First());     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Yan Li"&lt;/span&gt;, names.Last());     &lt;br /&gt;
}     &lt;br /&gt;
&lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Isolated&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.AddPerson"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddPerson_CalledOnce_IncreasesCountByOne()     &lt;br /&gt;
{     &lt;br /&gt;
    FakeData();     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; count = _personRepository.Count;     &lt;br /&gt;
&lt;br /&gt;
    _personRepository.AddPerson(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; { FirstName = &lt;span style="color: #a31515"&gt;"Thomas"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Weller"&lt;/span&gt; });     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(count + 1, _personRepository.Count);     &lt;br /&gt;
}     &lt;br /&gt;
&lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Isolated&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.RemovePerson"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RemovePerson_CalledOnce_DecreasesCountByOne()     &lt;br /&gt;
{     &lt;br /&gt;
    FakeData();     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; count = _personRepository.Count;     &lt;br /&gt;
&lt;br /&gt;
    _personRepository.RemovePerson(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; { PersonID = 33 });     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(count - 1, _personRepository.Count);     &lt;br /&gt;
}     &lt;br /&gt;
&lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Isolated&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.RemovePerson"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RemovePerson_ForWhomAnOfficeAssignmentExists_Throws()     &lt;br /&gt;
{     &lt;br /&gt;
    FakeData();     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Throws&amp;lt;&lt;span style="color: #2b91af"&gt;RepositoryException&lt;/span&gt;&amp;gt;(() =&amp;gt;     &lt;br /&gt;
        _personRepository.RemovePerson(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; { PersonID = 18 }));     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;I kept these tests deliberately simple to underpin the fact that Typemock-based tests don't need to be much different from non-faked tests, and also to make them comparable to the other options that are discussed here (the NDbUnit approach and the non-faked version, running your tests directly against a real instance of MS SQL Server, namely).&lt;/p&gt;
&lt;h1&gt;But wait, what if things are becoming somewhat more complex?&lt;/h1&gt;
&lt;p&gt;Admittedly (and intentionally), the above tests cover only some very simple test cases. This may be enough for some of your test scenarios: the 'normal' use cases, which may make up something well above 95% of what your application effectively is doing in production ("it just works"), but is easily covered with a few simple tests. The more interesting and important bits are the exceptional situations; the corner cases, where something unexpected happens. This is what consumes most of the time and effort in software development: To make an application robust and stable, and make it react in a predictable, user-friendly way even under exceptional circumstances.&lt;/p&gt;
&lt;p&gt;In such a situation (i.e. if you want to simulate some sort of exceptional condition), chances are that you will have to dive deep into the production code - or even some 3rd party code, if it is available - to find out what you will have to return from your &lt;em&gt;fake&lt;/em&gt;. A (still very simple) test of this kind could be this, for example:&lt;/p&gt;
&lt;p&gt;&lt;a name="MoreComplexTest"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 271px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Isolated&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetCourseMembers"&lt;/span&gt;)]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;))]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(&lt;span style="color: #a31515"&gt;""&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;))]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"NotExistingCourse"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;))]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetCourseMembers_WhenGivenVariousInvalidValues_Throws(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; courseTitle, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; expectedInnerExceptionType)     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #008000"&gt;// Generally return false from the expression '_schoolContext.Courses.Any(...)'&lt;/span&gt;     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; _schoolContext.Courses.Any(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;))     &lt;br /&gt;
           .WillReturn(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; exception = &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Throws&amp;lt;&lt;span style="color: #2b91af"&gt;RepositoryException&lt;/span&gt;&amp;gt;(() =&amp;gt;     &lt;br /&gt;
                                _personRepository.GetCourseMembers(courseTitle));     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsInstanceOfType(expectedInnerExceptionType, exception.InnerException);     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;This looks quite trivial, but it took me some minutes to understand that it's the &lt;font face="Courier New"&gt;Any()&lt;/font&gt; extension method that I had to fake here, and I also had to slightly refactor the &lt;font face="Courier New"&gt;FakeDataHolder()&lt;/font&gt; helper class to make this work. All in all, not too big a deal, you may say. True, but keep in mind that small things like that can easily add up to a huge amount of additional work (that your manager might not be willing to pay for)...&lt;/p&gt;
&lt;p&gt;The other situation in which using Typemock becomes somewhat more laborious is when you have to perform a lot of preparational work of the above described kind to simulate a regular scenario, which you would otherwise (when running against a real database) just take for granted, without thinking much about it. Look at this test, for example:&lt;/p&gt;
&lt;p&gt;&lt;a name="MoreComplexTest2"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 614px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Isolated&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetCourseMembers"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetCourseMembers_WhenGivenAnExistingCourse_ReturnsListOfStudents()     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #008000"&gt;// Avoid the ArgumentNullException&lt;/span&gt;     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; _schoolContext.Courses.Any(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;))     &lt;br /&gt;
           .WillReturn(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);     &lt;br /&gt;
    &lt;span style="color: #008000"&gt;// Always return true from the expression 'Person.StudentGrades.Any(...)'&lt;/span&gt;     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; fakePerson = &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.Fake.Instance&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt;();     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; fakePerson.StudentGrades.Any(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;))     &lt;br /&gt;
           .WillReturn(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.Swap.AllInstances&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt;()     &lt;br /&gt;
           .With(fakePerson);     &lt;br /&gt;
    &lt;span style="color: #008000"&gt;// Return the expected list of persons&lt;/span&gt;     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; _schoolContext.People)     &lt;br /&gt;
           .WillReturnCollectionValuesOf(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt;     &lt;br /&gt;
                                            {     &lt;br /&gt;
                                                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 9, FirstName = &lt;span style="color: #a31515"&gt;"Wayne"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Tang"}&lt;/span&gt;,     &lt;br /&gt;
                                                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 10, FirstName = &lt;span style="color: #a31515"&gt;"Meredith"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Alonso"}&lt;/span&gt;,     &lt;br /&gt;
                                                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 11, FirstName = &lt;span style="color: #a31515"&gt;"Sophia"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Lopez"}&lt;/span&gt;,     &lt;br /&gt;
                                                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 12, FirstName = &lt;span style="color: #a31515"&gt;"Meredith"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Browning"}&lt;/span&gt;,     &lt;br /&gt;
                                                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 14, FirstName = &lt;span style="color: #a31515"&gt;"Alexandra"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Walker"}&lt;/span&gt;,     &lt;br /&gt;
                                                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Person&lt;/span&gt; {PersonID = 22, FirstName = &lt;span style="color: #a31515"&gt;"Carson"&lt;/span&gt;, LastName = &lt;span style="color: #a31515"&gt;"Alexander"}&lt;/span&gt;     &lt;br /&gt;
                                            }     &lt;br /&gt;
                                            .AsQueryable());     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt; persons = _personRepository.GetCourseMembers(&lt;span style="color: #a31515"&gt;"Macroeconomics"&lt;/span&gt;);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Count(6, persons);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.ForAll(     &lt;br /&gt;
        persons,     &lt;br /&gt;
        @p =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;[] { 9, 10, 11, 12, 14, 22 }.Contains(@p.PersonID),     &lt;br /&gt;
        &lt;span style="color: #a31515"&gt;"Person has none of the expected IDs."&lt;/span&gt;);     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;The test asserts that, when asking for the members of a specific course, we actually are provided with the expected list, if we have set up the underlying &lt;font face="Courier New"&gt;ObjectContext&lt;/font&gt; &lt;em&gt;fake&lt;/em&gt; to return the correct data. (One word about the &lt;font face="Courier New"&gt;Isolate.Swap.AllInstances()&lt;/font&gt; expression here: It instructs Typemock to replace all future instances of the &lt;font face="Courier New"&gt;Person&lt;/font&gt; class with the here defined &lt;font face="Courier New"&gt;fakePerson&lt;/font&gt; object, whenever the code under test should create a new &lt;font face="Courier New"&gt;Person&lt;/font&gt;&lt;font face="Arial"&gt; instance.) &lt;/font&gt;See how the 'Arrange' part of the test blows up and also requires quite some intimate knowledge about the code under test, in order to provide the required return values (I've heard this once being called &lt;em&gt;Wishful mocking&lt;/em&gt;...)?&lt;/p&gt;
&lt;p&gt;Sometimes, especially when dealing with a legacy codebase that you cannot change, this is the only option at all to put such code under test, but it easily can mean that you will have to do a lot of work, if you will have to account for all kinds of database relations, triggers, check constraints, stored procedures and stuff like that. How much, will largely depend on the complexity of the underlying database (and of course also on the complexity of the code under test)...&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Typemock is a powerful and flexible tool to handle the here described EF/MSSQL scenario. It's blazingly fast, fully isolates your system under test from any external data source, and lets you quickly and easily adapt/refactor your test code if you need to. All your test data are defined directly in the test code, so chances are high that you get immediate feedback in form of a compiler error when you have changed your database schema (and consequently the EF conceptual model) for some reason.&lt;/p&gt;
&lt;p&gt;The downsides are more practical in nature: As I illustrated above, it can be a lot of work to fake certain scenarios with Typemock, so be prepared that it may not always be straightforward and easy to author tests with the help of the tool (but there will be a rich reward for your efforts...). Also, Typemock is a commercial tool,which means that it does not come for free in financial terms. You will have to make the explicit decision at some point whether it's worth its price in your specific situation or not.&lt;/p&gt;
&lt;p&gt;Whereas this part of the article series has shown how the &lt;a target="_blank" href="http://www.typemock.com/typemock-isolator-product3/"&gt;Typemock Isolator&lt;/a&gt; tool can be used to deal with a scenario where an application sits on top of an MS Entity Framework class model, the next part will accomplish the same with the &lt;a target="_blank" href="http://code.google.com/p/ndbunit/"&gt;NDbUnit&lt;/a&gt; framework.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;The sample solution&lt;/h1&gt;
&lt;p&gt;A sample solution (VS 2010) with the code from this article series is available via &lt;a target="_blank" href="https://bitbucket.org/thomas.weller"&gt;my Bitbucket account&lt;/a&gt; from &lt;a target="_blank" href="https://bitbucket.org/thomas.weller/testingentityframeworkapplications/overview"&gt;here&lt;/a&gt; (Bitbucket is a hosting site for &lt;a target="_blank" href="http://mercurial.selenic.com/"&gt;Mercurial&lt;/a&gt; repositories. The repositories may also be accessed with the &lt;a target="_blank" href="http://git-scm.com/"&gt;Git&lt;/a&gt; and &lt;a target="_blank" href="http://subversion.apache.org/"&gt;Subversion&lt;/a&gt; SCMs - consult the documentation for details. In addition, it is possible to download the solution simply as a zipped archive – via the 'get source' button on the very right.). The solution contains some more tests against the &lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt; class, which are not shown here. Also, it contains database scripts to create and fill the &lt;font face="Courier New"&gt;School&lt;/font&gt; sample database.&lt;/p&gt;
&lt;p&gt;To compile and run, the solution expects the Gallio/MbUnit framework to be installed (which is free and can be downloaded from &lt;a target="_blank" href="http://www.gallio.org/Downloads.aspx"&gt;here&lt;/a&gt;), the NDbUnit framework (which is also free and can be downloaded from &lt;a target="_blank" href="http://code.google.com/p/ndbunit/downloads/list"&gt;here&lt;/a&gt;), and the Typemock Isolator tool (a fully functional 30day-trial is available &lt;a target="_blank" href="http://www.typemock.com/download/"&gt;here&lt;/a&gt;). Moreover, you will need an instance of the Microsoft SQL Server DBMS, and you will have to adapt the connection strings in the test projects &lt;font face="Courier New"&gt;App.config&lt;/font&gt; files accordingly.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table width="580" cellspacing="2" cellpadding="6" border="0" style="background-image: url(http://gwb.blob.core.windows.net/thomasweller/social/pictures/socialb-580x100.gif); background-repeat: no-repeat; background-position: -5px 50%"&gt;
    &lt;tbody&gt;
        &lt;tr style="padding-top: 4px"&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="kickit"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url="&gt;&lt;img width="88" height="22" border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=" alt="kickit" title="Kick it!" id="kick" style="position: relative; display: inline; cursor: pointer; padding-top: 6px; top: 4px" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="shoutit"&gt;&lt;a href="http://dotnetshoutout.com/Submit?url="&gt;&lt;img border="0" src="http://dotnetshoutout.com/image.axd?url=" alt="shoutit" title="Shout it!" id="shout" style="position: relative; display: inline; cursor: pointer; padding-top: 6px; top: 4px" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="330" valign="middle" align="left"&gt;
            &lt;div id="zoneit"&gt;&lt;iframe width="150" scrolling="no" height="20" frameborder="0" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&amp;amp;url=&amp;amp;title=" title="Zone it!" id="dzoneframe" style="position: relative; top: 4px"&gt;&lt;/iframe&gt;&lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="middle" colspan="3"&gt;&lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/delicious-32x32.png" alt="delicious" onclick="setBookmark('delicious');" title="Bookmark this on Delicious." id="delicious" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;a href="http://www.facebook.com/sharer.php" id="fbshare"&gt;&lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/facebook-48x48.png" alt="facebook" title="Share this on Facebook." id="facebook" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; left: 2px" /&gt;&lt;/a&gt; &lt;img width="34" height="34" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/digg-48x48.png" alt="digg" onclick="setBookmark('digg');" title="Digg this." id="digg" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/reddit-48x48.png" alt="reddit" onclick="setBookmark('reddit');" title="Reddit this." id="reddit" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;img width="34" height="34" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/linkedin-48x48.png" alt="linkedin" onclick="setBookmark('linkedin');" title="Share this on LinkedIn." id="linkedin" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/stumbleupon-48x48.png" alt="stumbleupon" onclick="setBookmark('stumbleupon');" title="Stumble!" id="stumbleupon" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/technorati-48x48.png" alt="technorati" onclick="setBookmark('technorati')" title="Add this to Technorati." id="technorati" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; padding-top: 1px; left: 2px" /&gt; &lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/mrwong-32x32.png" alt="mrwong" onclick="setBookmark('mrwong');" title="Bookmark this on Mister Wong." id="mrwong" style="position: relative; border-right-width: 0px; margin: 1px 0px 0px 1px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/yahoo-48x48.png" alt="yahoo" onclick="setBookmark('yahoobkm')" title="Bookmark this on Yahoo." id="yahoobkm" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/google-48x48.png" alt="google-48x48" onclick="setBookmark('googlebkm');" title="Bookmark this on Google." id="googlebkm" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/twitter-48x48.png" alt="twitter" onclick="BitlyClient.shorten(document.location, 'BitlyCB.shortenResponse');" title="Tweet this (with bit.ly URL)." id="twitter" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;img width="31" height="31" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/email-32x32.png" alt="email" onclick="mailpage();" title="Send a link via E-Mail." id="mail" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt; &lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/favorites-star-128x128.png" alt="favorites" onclick="bookmarkInBrowser();" title="Bookmark this page in your browser." id="bookmark" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/147613.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2011/11/08/testing-entity-framework-applications-pt.-2-typemock.aspx</guid>
            <pubDate>Tue, 08 Nov 2011 06:27:34 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/147613.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2011/11/08/testing-entity-framework-applications-pt.-2-typemock.aspx#feedback</comments>
            <slash:comments>9</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/147613.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Testing Entity Framework applications, pt. 1</title>
            <category>Unit Testing/TDD</category>
            <category>Open Source</category>
            <category>Automation</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2011/11/06/testing-entity-framework-applications-pt.-1.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2011/11/06/testing-entity-framework-applications-pt.-1.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2011/11/06/testing-entity-framework-applications-pt.-1.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;For good or bad, Microsoft’s &lt;a href="http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework" target="_blank"&gt;Entity Framework&lt;/a&gt; (EF) has become one of the most widely used &lt;a href="http://en.wikipedia.org/wiki/List_of_object-relational_mapping_software#.NET" target="_blank"&gt;ORM tools&lt;/a&gt; out there. While some may state that it's not among the better ones (or that it's not even a real ORM), it’s definitely the most convenient one: its Visual Studio integration and consequently its integration with the &lt;a href="http://www.microsoft.com/sqlserver/en/us/default.aspx" target="_blank"&gt;MS SQL Server&lt;/a&gt; database is unparalleled. This is especially relevant to people who haven’t used the concept of &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank"&gt;object-relational mapping&lt;/a&gt; before - there's almost no initial learning curve associated with the framework. While it would theoretically be possible to use EF with a DBMS other than MS SQL Server, it’s in practice almost exclusively used in combination with Microsoft's database engine.&lt;/p&gt;
&lt;p&gt;Lately, I wondered how you would ‘mock’ EF’s data model - together with an underlying MSSQL database - in such a scenario. The question arose in the broader context of writing integration tests (automated UI tests, to be exact) for a legacy application which uses the described EF/MSSQL combo as its data store mechanism. It turned out that the possible strategies are not very obvious and require some additional tools and effort...&lt;/p&gt;
&lt;hr /&gt;
&lt;p align="justify"&gt;This is part 1 of a three part series that examines some ways to cope with the above described scenario. While the next two parts are more concerned with concrete implementation details, this part discusses some more general considerations on the issue and introduces the sample application which serves as a 'target' for the tests that will be presented in the latter parts.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Handling the data layer in tests&lt;/h1&gt;
&lt;p&gt;In general, things tend to become a bit tricky when it comes to testing database-related parts of an application. &lt;em&gt;But how would you go for database testing?&lt;/em&gt;  is an often heard question from people who are new to unit testing. For good reasons, because database related testing is one of the more demanding areas in the testing field, mainly because of two aspects:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;There’s not a single, easy-to-use framework to test the database in complete isolation – no matter what DBMS you use.&lt;/li&gt;
    &lt;li&gt;More often than not, the business logic of the application is partly implemented by the application's data access code, and partly by the database itself (e.g. through stored procs, triggers, constraints etc.).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Moreover, if we take a closer look at the question (&lt;em&gt;How would you go for database testing?&lt;/em&gt;), it becomes clear that, effectively, we're talking about two different scenarios here:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Actually &lt;em&gt;testing&lt;/em&gt; the data layer of a project.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Stubbing out&lt;/em&gt; the data layer to enable other (integration-style) tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Testing the data layer&lt;/h4&gt;
&lt;p&gt;The best way to test an application’s data store mechanism is to test it in team with the data access code that sits on top of it. Usually, your test code will access the production code which is closest to the database in such a case. Roy Osherove, in his book &lt;a href="http://artofunittesting.com/" target="_blank"&gt;The Art Of Unit Testing&lt;/a&gt;, has the following to say about it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I usually write integration-style tests for the data layer (the part of the app structure that talks directly to the database) in my applications because data logic is almost always divided between the application logic and the database itself (triggers, security rules, referential integrity, and so on). […], the only way to make sure it works in tests is to couple testing the data-layer logic to the real database. &lt;/em&gt;(p. 277)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For a project with EF, you would write tests against the EF data model, thus acting as a data model client. The underlying database could be kept constant in such a scenario for example by wrapping each test in a database transaction, or by resetting the entire database at the required points – either by running some scripts or by using the DB server's backup/restore mechanism.&lt;/p&gt;
&lt;p&gt;I won't go into more details here because, as described above, it's the second scenario which served as a starting point for this article series:&lt;/p&gt;
&lt;h4&gt;Stubbing out the data layer&lt;/h4&gt;
&lt;p&gt;Besides the necessity to test an application's data layer directly, we also need a way to simulate the entire data access functionality of an application in order to run other kinds of (integration-style) tests that somehow rely on the data access part, without actually testing it.&lt;/p&gt;
&lt;p&gt;If your application architecture is made up along the lines of &lt;a href="http://en.wikipedia.org/wiki/Domain-driven_design" target="_blank"&gt;Domain-driven design&lt;/a&gt;, the general layer architecture might look roughly like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/6c51dee24005_1003C/LayerArchitecture_7.png"&gt;&lt;img width="356" border="0" height="468" style="background-image: none; border-right-width: 0px; margin: 3px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="LayerArchitecture" alt="LayerArchitecture" src="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/6c51dee24005_1003C/LayerArchitecture_thumb_2.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note that this is only one out of many possible architectures, and it's in no way mandatory for using the tools and techniques which are presented here.&lt;/p&gt;
&lt;p&gt;The important piece is that you have some client code against that you want to write tests, and that there is an EF data model somewhere down the chain.&lt;/p&gt;
&lt;p&gt;(Note: the 'client' here actually is the &lt;em&gt;Repository&lt;/em&gt;, and &lt;em&gt;Client code&lt;/em&gt; could be anything that calls it. The diagram admittedly is somewhat misleading in that respect...)&lt;/p&gt;
&lt;p&gt;Such tests could be for example integration tests against an application's Business Logic layer, or some User Acceptance Tests on the UI level, involving a UI automation framework like e.g. &lt;a href="http://watin.org/" target="_blank"&gt;WatiN&lt;/a&gt;, &lt;a href="http://seleniumhq.org/" target="_blank"&gt;Selenium&lt;/a&gt;, or &lt;a href="http://white.codeplex.com/" target="_blank"&gt;White&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Also, you could use any DBMS that works with EF (&lt;a href="http://stackoverflow.com/questions/1865352/a-list-of-entity-framework-providers-for-various-databases" target="_blank"&gt;here&lt;/a&gt;'s a list). The basic story remains the same...&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h4&gt;Special issues with MS Entity Framework&lt;/h4&gt;
&lt;p&gt;Writing tests against code that invokes EF is not easy – obviously, the &lt;em&gt;Testing&lt;/em&gt; issue wasn't a concern at all when developing the framework. The two biggest stumbling blocks on the way to writing tests are:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;EF stores the used data provider type in its mapping file (*.edmx), which in turn is compiled as an embedded resource into the respective assembly. In consequence this means: The specification of the DBMS technology is part of the application code and cannot be changed later. So there's no way to replace the underlying database with an embedded one like &lt;a href="http://www.sqlite.org/" target="_blank"&gt;SQLite&lt;/a&gt; or &lt;a href="http://www.microsoft.com/sqlserver/en/us/editions/compact.aspx" target="_blank"&gt;SQL Server CE&lt;/a&gt;. You only can alter the &lt;em&gt;location&lt;/em&gt; of the used database, but you have to stick to the once chosen &lt;em&gt;database type&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;EF does not adhere to the standards of &lt;a href="http://en.wikipedia.org/wiki/Interface-based_programming" target="_blank"&gt;Interface-based programming&lt;/a&gt;. There are abstract classes, sealed classes, and classes with non-public constructors everywhere – but not a single interface. This means that using one of the free mocking frameworks like e.g. &lt;a href="http://code.google.com/p/moq/" target="_blank"&gt;Moq&lt;/a&gt;,  &lt;a href="http://code.google.com/p/fakeiteasy/" target="_blank"&gt;fakeiteasy&lt;/a&gt;, or &lt;a href="http://www.nmock.org/" target="_blank"&gt;NMock&lt;/a&gt; is also not an option.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;The different approaches&lt;/h4&gt;
&lt;p&gt;The above outlined restrictions leave us with these options (at least these are the ones that came to my mind):&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;We have a 'static' database in place and wrap each test into a database transaction, or&lt;/li&gt;
    &lt;li&gt;we mock (or fake) the EF code directly, using the (commercial) &lt;a href="http://www.typemock.com/typemock-isolator-product3/" target="_blank"&gt;Typemock Isolator&lt;/a&gt; tool, or&lt;/li&gt;
    &lt;li&gt;we set up a dedicated instance of the SQL Server database and feed it with the required test data via the &lt;a href="http://code.google.com/p/ndbunit/" target="_blank"&gt;NDbUnit&lt;/a&gt; library.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;font color="#ffffff"&gt;Regarding the first strategy, I won't discuss it here in depth (note however that it is included with the sample solution – see the &lt;font face="Courier New"&gt;CourseManager.Test.MsSqlServer&lt;/font&gt; project), because this article series is more about &lt;em&gt;mocking test data&lt;/em&gt;, whereas this approach uses a predefined set of data. Of course, you could extend it in various ways to cope with specific needs, but this would be a different story. I'd only like to mention here that this approach could bring its own set of problems:&lt;/font&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;font color="#ffffff"&gt;You're writing the tests against a fixed set of data, which makes this approach somewhat inflexible and sometimes may even prevent you from covering a specific scenario (of course there are various ways to cope with such a situation, but they are not easily implemented and require quite some additional effort).&lt;/font&gt;&lt;/li&gt;
    &lt;li&gt;&lt;font color="#ffffff"&gt;Because you're heavily using transactions, it's easy to run into specific issues from this side (especially if your test wants to use a transaction of its own, when the entire test method is already wrapped in a transaction).&lt;/font&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;font color="#ffffff"&gt;The other two approaches (Typemock and NDbUnit) are fairly different in how they do things: &lt;/font&gt;&lt;font color="#ffffff"&gt;While the Typemock approach directly intercepts the calls to the EF classes, NDbUnit manipulates the underlying database. In other words, the two approaches act upon different levels of an application's data access system, as shown below:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;img width="574" border="0" height="454" style="background-image: none; border-right-width: 0px; margin: 9px auto 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="LayerArchitectureWithTools" alt="LayerArchitectureWithTools" src="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/6c51dee24005_1003C/LayerArchitectureWithTools_3.png" /&gt;&lt;/p&gt;
&lt;p&gt;Also, the two methodologies are not equivalent in terms of what is best in which scenario. We’ll see that in more detail in the next parts, but the bottom line is this:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Typemock is the preferable tool when &lt;em&gt;developing&lt;/em&gt; an application or feature, because it's easy to alter a return value, you usually get an immediate compile error if your test code is not in sync with the database schema, and it's lightning fast, because there is no disk I/O whatsoever involved. The biggest drawback of Typemock is the fact that things easily become very expensive and hard to maintain when you have to fake things like referential integrity constraints and/or a massive amount of data.&lt;/li&gt;
    &lt;li&gt;NDbUnit on the other hand shines when writing tests against a relatively stable database schema, having a huge amount of data, or when you are heavily concerned with referential integrity constraints and their interrelations. It lets you declare all of your test data in external xml files, which then can be loaded on a per-test basis.  The most prominent downside here lies in the framework's lacking robustness against schema changes: If there are any error messages, then you will get them only during runtime, and chances are big that the error messages will not directly point you to the underlying error.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;The sample target application: Course Manager&lt;/h1&gt;
&lt;p&gt;We start with the Course Manager sample application as taken from the &lt;a href="http://msdn.microsoft.com/en-us/library/bb399182.aspx" target="_blank"&gt;MSDN Quickstart&lt;/a&gt;. It’s a very simple EF app with only the bare minimum:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;a database (‘&lt;font face="Courier New"&gt;School’&lt;/font&gt;)&lt;/li&gt;
    &lt;li&gt;an EF data model on top of the &lt;font face="Courier New"&gt;School&lt;/font&gt; database&lt;/li&gt;
    &lt;li&gt;a form to display/edit these data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;font color="#ffffff"&gt;Here's a screenshot:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/6c51dee24005_1003C/CourseManagerForm_thumb3_2.gif"&gt;&lt;img width="374" border="0" height="337" style="background-image: none; border-right-width: 0px; margin: 3px 210px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="CourseManagerForm_thumb3" alt="CourseManagerForm_thumb3" src="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/6c51dee24005_1003C/CourseManagerForm_thumb3_thumb.gif" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this very simple app, the form then is the client of the data model.&lt;/p&gt;
&lt;h4&gt;The data connection&lt;/h4&gt;
&lt;p&gt;The connection string for the application's database is defined in the &lt;font face="Courier New"&gt;App.config&lt;/font&gt;. The EF connection string entirely contains the normal MS SQL Server connection string, so you may easily modify name and location of the underlying database (but – as pointed out above – you cannot change the type of the provider). The &lt;font face="Courier New"&gt;App.config&lt;/font&gt; looks like this:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 147px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;
&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;xml&lt;/span&gt;&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;version&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;1.0&lt;/span&gt;"&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;"&lt;span style="color: blue"&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;add&lt;/span&gt;&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SchoolEntities&lt;/span&gt;"&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;         &lt;/span&gt;&lt;span style="color: red"&gt;connectionString&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;metadata=res://*/School.csdl|res://*/School.ssdl|res://*/School.msl;provider=System.Data.SqlClient;provider connection string=&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;Data Source=&lt;font color="#000000"&gt;&amp;lt;server instance name&amp;gt;&lt;/font&gt;;Initial Catalog=School;Integrated Security=True;Pooling=False;MultipleActiveResultSets=True&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;quot;&lt;/span&gt;"&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;providerName&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Data.EntityClient&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4&gt;Adding some ‘meat’ to the target&lt;/h4&gt;
&lt;p&gt;In theory this would be enough to demonstrate the approach: We could write UI tests against the form while stubbing out the database – in fact this would be very close to what might happen in real development practice. But because UI tests are a quite demanding issue in itself and require at least some additional testing framework (and thus would introduce further complexity), I modified/extended the original solution  to have a separate data access layer with a simple repository. This resulted in the assembly&lt;font face="Courier New"&gt; CourseManager.Data,&lt;/font&gt; which looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/6c51dee24005_1003C/DataLayer_thumb4_2.png"&gt;&lt;img width="571" border="0" height="804" style="background-image: none; border-right-width: 0px; margin: 5px auto 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DataLayer_thumb4" alt="DataLayer_thumb4" src="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/6c51dee24005_1003C/DataLayer_thumb4_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see, I added a &lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt; class, which acts as our sample client for the EF data model. This will be the class that we’ll write our tests against (Again: It could also be any other code which sits on top of an EF data model.).&lt;/p&gt;
&lt;h4&gt;General code and fixture layout&lt;/h4&gt;
&lt;p&gt;Entity Framework encapsulates its entire database stuff as well as all data entities from the conceptual model in one single class which derives from the &lt;font face="Courier New"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.aspx" target="_blank"&gt;ObjectContext&lt;/a&gt;&lt;/font&gt; base class. This is a horrible complex and far too long beast, and it's doing way too much different things (in other words: there's absolutely no &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns" target="_blank"&gt;Separation of concerns&lt;/a&gt;). The EF designer combines this base class with the conceptual model from our &lt;font face="Courier New"&gt;School&lt;/font&gt; database and generates a &lt;font face="Courier New"&gt;SchoolEntities&lt;/font&gt; class for us, which serves as our single access point to the database. Consequently, our sample repository class (&lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt;), which is there to encapsulate all the concrete data access code from the rest of the application, gets an instance of this &lt;font face="Courier New"&gt;SchoolEntities&lt;/font&gt; class via its c'tor (This is an example for &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection" target="_blank"&gt;Dependency Injection&lt;/a&gt;, a coding  technique which is generally very recommendable to write clean, maintainable code, and is invaluable if you want to design your code for testability.)&lt;/p&gt;
&lt;p&gt;So the first part of our test fixture for the &lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt; class will be this (using &lt;a href="http://www.gallio.org" target="_blank"&gt;Gallio&lt;/a&gt;):&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 451px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;TestFixture&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;PersonRepository&lt;/span&gt;))]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Metadata&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"MSDN Entity Framework Quickstart URL"&lt;/span&gt;,     &lt;br /&gt;
          &lt;span style="color: #a31515"&gt;"http://msdn.microsoft.com/en-us/library/bb399182.aspx"&lt;/span&gt;)]     &lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Description&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Tests against the 'School' database as it is provided by MS. "&lt;/span&gt; +     &lt;br /&gt;
             &lt;span style="color: #a31515"&gt;"This expects the 'School' database from the quickstart sample."&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PersonRepositoryFixture&lt;/span&gt;     &lt;br /&gt;
{     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Fields     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SchoolEntities&lt;/span&gt; _schoolContext;     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PersonRepository&lt;/span&gt; _personRepository;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #endregion&lt;/span&gt; &lt;span style="color: #008000"&gt;// Fields&lt;/span&gt;     &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    #region&lt;/span&gt; Setup/TearDown     &lt;br /&gt;
&lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;SetUp&lt;/span&gt;]     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SetUp()     &lt;br /&gt;
    {     &lt;br /&gt;
        _schoolContext = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SchoolEntities&lt;/span&gt;();     &lt;br /&gt;
        _personRepository = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PersonRepository&lt;/span&gt;(_schoolContext);     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    ...&lt;/div&gt;
&lt;p&gt;Here, we declare an instance of the &lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt; class, and we initialize it with a &lt;font face="Courier New"&gt;SchoolEntities&lt;/font&gt; object. By using a &lt;font face="Courier New"&gt;&lt;a href="http://www.gallio.org/api/html/T_MbUnit_Framework_SetUpAttribute.htm" target="_blank"&gt;Setup&lt;/a&gt;&lt;/font&gt; method, we do this initalization for each single test. - Because the &lt;font face="Courier New"&gt;ObjectContext&lt;/font&gt; is a highly stateful class (for example, it holds a cache with all the already loaded entities), and we want to make sure that our test outcomes are not influenced by previous operations.&lt;/p&gt;
&lt;h4&gt;And finally: the first test&lt;/h4&gt;
&lt;p&gt;To make things a little bit more interesting, I also extended the &lt;font face="Courier New"&gt;Person&lt;/font&gt; entity to have a &lt;font face="Courier New"&gt;GetFullName()&lt;/font&gt; method which returns the full name of the &lt;font face="Courier New"&gt;Person&lt;/font&gt; according to the &lt;font face="Courier New"&gt;provided nameOrdering&lt;/font&gt; argument:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 287px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;
&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;partial&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Person&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;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; GetFullName(&lt;span style="color: rgb(43,145,175)"&gt;NameOrdering&lt;/span&gt; nameOrdering)&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
    {&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
        &lt;span style="color: blue"&gt;switch&lt;/span&gt; (nameOrdering)&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
        {&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
        &lt;span style="color: blue"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;NameOrdering&lt;/span&gt;.Normal:&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
            &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;.Format(&lt;span style="color: rgb(163,21,21)"&gt;"{0} {1}"&lt;/span&gt;, _FirstName, _LastName);&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
        &lt;span style="color: blue"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;NameOrdering&lt;/span&gt;.List:&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
            &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;.Format(&lt;span style="color: rgb(163,21,21)"&gt;"{0}, {1}"&lt;/span&gt;, _LastName, _FirstName);&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
        &lt;span style="color: blue"&gt;default&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; &lt;span style="color: rgb(43,145,175)"&gt;InvalidEnumArgumentException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"nameOrdering"&lt;/span&gt;, (&lt;span style="color: blue"&gt;int&lt;/span&gt;)nameOrdering, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;NameOrdering&lt;/span&gt;));&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
        }&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
    }&lt;/pre&gt;
&lt;pre style="margin: 0px"&gt;
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Consequently, the &lt;font face="Courier New"&gt;PersonRepository&lt;/font&gt; class has a corresponding method &lt;font face="Courier New"&gt;GetNameList()&lt;/font&gt;, which returns an alphabetically sorted list of these &lt;font face="Courier New"&gt;Person&lt;/font&gt; names:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 325px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; GetNameList(&lt;span style="color: #2b91af"&gt;NameOrdering&lt;/span&gt; nameOrdering)     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; fullNames =  &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;(     &lt;br /&gt;
            _entities.People     &lt;br /&gt;
                     .ToList()     &lt;br /&gt;
                     .Select(@p =&amp;gt; @p.GetFullName(nameOrdering)));     &lt;br /&gt;
       fullNames.Sort();     &lt;br /&gt;
&lt;br /&gt;
       &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; fullNames;     &lt;br /&gt;
    }     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt; exception)     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RepositoryException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Error getting person names."&lt;/span&gt;, exception);     &lt;br /&gt;
    }     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;And finally, the tests for &lt;font face="Courier New"&gt;GetNameList()&lt;/font&gt;&lt;font face="Arial"&gt; look like this then:&lt;/font&gt;&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 380px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetNameList"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetNameList_ListOrdering_ReturnsTheExpectedFullNames()     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; names =     &lt;br /&gt;
        _personRepository.GetNameList(&lt;span style="color: #2b91af"&gt;NameOrdering&lt;/span&gt;.List);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Count(34, names);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Abercrombie, Kim"&lt;/span&gt;, names.First());     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Zheng, Roger"&lt;/span&gt;, names.Last());     &lt;br /&gt;
}     &lt;br /&gt;
&lt;br /&gt;
[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MultipleAsserts&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"PersonRepository.GetNameList"&lt;/span&gt;)]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetNameList_NormalOrdering_ReturnsTheExpectedFullNames()     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; names =     &lt;br /&gt;
        _personRepository.GetNameList(&lt;span style="color: #2b91af"&gt;NameOrdering&lt;/span&gt;.Normal);     &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Count(34, names);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Alexandra Walker"&lt;/span&gt;, names.First());     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Yan Li"&lt;/span&gt;, names.Last());     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;Nothing complicated or surprising here (in general, tests should always be that simple and 'trivial'): We just know what's in the database and check the repositories' corresponding list to correctly mirror this.&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Ok, that's it for now. We've covered a lot of ground to set the stage for the forthcoming parts - maybe too much, but I didn't want to close the first part without presenting a single test ;-).&lt;/p&gt;
&lt;p&gt;This first part of the article series introduced the sample application that will be used as a target for our tests, discussed some general aspects of database-related testing, and also presented some of the more specific issues that you will have to handle when dealing with MS Entity Framework.  The next two parts then will discuss the here outlined approaches with the Typemock and NDbUnit tools in some more detail, building on top of the here described &lt;font face="Courier New"&gt;CourseManager&lt;/font&gt; sample application.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;The sample solution&lt;/h1&gt;
&lt;p&gt;A sample solution (VS 2010) with the code from this article series is available via &lt;a href="https://bitbucket.org/thomas.weller" target="_blank"&gt;my Bitbucket account&lt;/a&gt; from &lt;a href="https://bitbucket.org/thomas.weller/testingentityframeworkapplications/overview" target="_blank"&gt;here&lt;/a&gt; (Bitbucket is a hosting site for &lt;a href="http://mercurial.selenic.com/" target="_blank"&gt;Mercurial&lt;/a&gt; repositories. The repositories may also be accessed with the &lt;a href="http://git-scm.com/" target="_blank"&gt;Git&lt;/a&gt; and &lt;a href="http://subversion.apache.org/" target="_blank"&gt;Subversion&lt;/a&gt; SCMs - consult the documentation for details. In addition, it is possible to download the solution simply as a zipped archive – via the 'get source' button on the very right.). The solution contains some more tests against the PersonRepository class, which are not shown here. Also, it contains database scripts to create and fill the &lt;font face="Courier New"&gt;School&lt;/font&gt; sample database.&lt;/p&gt;
&lt;p&gt;To compile and run, the solution expects the Gallio/MbUnit framework to be installed (which is free and can be downloaded from &lt;a href="http://www.gallio.org/Downloads.aspx" target="_blank"&gt;here&lt;/a&gt;), the NDbUnit framework (which is also free and can be downloaded from &lt;a href="http://code.google.com/p/ndbunit/downloads/list" target="_blank"&gt;here&lt;/a&gt;), and the Typemock Isolator tool (a fully functional 30day-trial is available &lt;a href="http://www.typemock.com/download/" target="_blank"&gt;here&lt;/a&gt;). Moreover, you will need an instance of the Microsoft SQL Server DBMS, and you will have to adapt the connection strings in the test projects &lt;font face="Courier New"&gt;App.config&lt;/font&gt; files accordingly.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table width="580" cellspacing="2" cellpadding="6" border="0" style="background-image: url(http://gwb.blob.core.windows.net/thomasweller/social/pictures/socialb-580x100.gif); background-repeat: no-repeat; background-position: -5px 50%"&gt;
    &lt;tbody&gt;
        &lt;tr style="padding-top: 4px"&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="kickit"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url="&gt;&lt;img width="88" border="0" height="22" style="position: relative; display: inline; cursor: pointer; padding-top: 6px; top: 4px" id="kick" title="Kick it!" alt="kickit" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="shoutit"&gt;&lt;a href="http://dotnetshoutout.com/Submit?url="&gt;&lt;img border="0" style="position: relative; display: inline; cursor: pointer; padding-top: 6px; top: 4px" id="shout" title="Shout it!" alt="shoutit" src="http://dotnetshoutout.com/image.axd?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="330" valign="middle" align="left"&gt;
            &lt;div id="zoneit"&gt;&lt;iframe width="150" height="20" frameborder="0" scrolling="no" style="position: relative; top: 4px" id="dzoneframe" title="Zone it!" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&amp;amp;url=&amp;amp;title="&gt;&lt;/iframe&gt;&lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="middle" colspan="3"&gt;&lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="delicious" title="Bookmark this on Delicious." onclick="setBookmark('delicious');" alt="delicious" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/delicious-32x32.png" /&gt; &lt;a id="fbshare" href="http://www.facebook.com/sharer.php"&gt;&lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; left: 2px" id="facebook" title="Share this on Facebook." alt="facebook" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/facebook-48x48.png" /&gt;&lt;/a&gt; &lt;img width="34" border="0" height="34" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="digg" title="Digg this." onclick="setBookmark('digg');" alt="digg" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/digg-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="reddit" title="Reddit this." onclick="setBookmark('reddit');" alt="reddit" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/reddit-48x48.png" /&gt; &lt;img width="34" border="0" height="34" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="linkedin" title="Share this on LinkedIn." onclick="setBookmark('linkedin');" alt="linkedin" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/linkedin-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="stumbleupon" title="Stumble!" onclick="setBookmark('stumbleupon');" alt="stumbleupon" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/stumbleupon-48x48.png" /&gt; &lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; padding-top: 1px; left: 2px" id="technorati" title="Add this to Technorati." onclick="setBookmark('technorati')" alt="technorati" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/technorati-48x48.png" /&gt; &lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; margin: 1px 0px 0px 1px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="mrwong" title="Bookmark this on Mister Wong." onclick="setBookmark('mrwong');" alt="mrwong" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/mrwong-32x32.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="yahoobkm" title="Bookmark this on Yahoo." onclick="setBookmark('yahoobkm')" alt="yahoo" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/yahoo-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="googlebkm" title="Bookmark this on Google." onclick="setBookmark('googlebkm');" alt="google-48x48" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/google-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="twitter" title="Tweet this (with bit.ly URL)." onclick="BitlyClient.shorten(document.location, 'BitlyCB.shortenResponse');" alt="twitter" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/twitter-48x48.png" /&gt; &lt;img width="31" border="0" height="31" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="mail" title="Send a link via E-Mail." onclick="mailpage();" alt="email" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/email-32x32.png" /&gt; &lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="bookmark" title="Bookmark this page in your browser." onclick="bookmarkInBrowser();" alt="favorites" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/favorites-star-128x128.png" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/147590.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2011/11/06/testing-entity-framework-applications-pt.-1.aspx</guid>
            <pubDate>Sun, 06 Nov 2011 09:25:07 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/147590.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2011/11/06/testing-entity-framework-applications-pt.-1.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/147590.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Some myths of 'Textbook-TDD', and why they are wrong</title>
            <category>General programming/C#</category>
            <category>Unit Testing/TDD</category>
            <category>Architecture and Design</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2011/10/31/some-myths-of-textbook-tdd-and-why-they-are-wrong.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2011/10/31/some-myths-of-textbook-tdd-and-why-they-are-wrong.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2011/10/31/some-myths-of-textbook-tdd-and-why-they-are-wrong.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;During the last months, I was (for some reasons that are not related to programming) working for a dev shop where software development was done the 'traditional' way: You just write your application's production code, do it as good as you can, and hopefully it will be good enough and no problems will occur in production (this is HDD: Hope-driven development).&lt;/p&gt;
&lt;p&gt;Anyway, after I had finished this contract, I felt the need to review some core aspects of what I think is &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank"&gt;Test-driven development&lt;/a&gt;. And while I was doing this, I noticed that some principles (or dogmas, if you prefer) of TDD - you may read them in books or they might be presented to you in some other way when you're learning about TDD - just don't make no sense to me anymore. This post discusses some of the more prominent things in TDD that I don't buy...&lt;/p&gt;
&lt;h4&gt;#1: "A not compiling test is a failing test"&lt;/h4&gt;
&lt;p&gt;Huh? Sorry, but no.&lt;/p&gt;
&lt;p&gt;A not compiling test is nothing but defective code that is not accepted by the compiler. And a compiler error has exactly nothing to do with the TDD process – it doesn't tell me anything relevant other than that my code is faulty.&lt;/p&gt;
&lt;p&gt;Suppose, for example, that you have the following test:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; width: 589px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 126px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SomeTest()     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; someClass = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SomeClass&lt;/span&gt;();     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; result = someClass.ReturnSomeValue(8);     &lt;br /&gt;
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(8, result);     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;If you try to compile this without having a skeleton of &lt;font face="Courier New"&gt;SomeClass&lt;/font&gt; and &lt;font face="Courier New"&gt;ReturnSomeValue()&lt;/font&gt; in place, then the C# compiler will give you this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/44273120c499_7366/image_2.png"&gt;&lt;img width="603" border="0" height="45" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" alt="image" src="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/44273120c499_7366/image_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; What does it say? Well, it tells you exactly one thing: You're trying to reference a symbol that the compiler cannot resolve. Nothing more. The error could come from everywhere in your code, there's nothing on it that makes it somehow specific to testing. So how could one conclude from this error message that it is (or at least is somehow referring to) a failing test?&lt;/p&gt;
&lt;p&gt;To really have a failing test, and not just a compiler error, you need to have the following in place:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; width: 589px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 127px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SomeClass&lt;/span&gt;     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ReturnSomeValue(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; val)     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #00008b"&gt;NotImplementedException&lt;/span&gt;();     &lt;br /&gt;
    }     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;If you then run the test again, it will compile and give you something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/44273120c499_7366/image_4.png"&gt;&lt;img width="603" border="0" height="117" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" alt="image" src="http://gwb.blob.core.windows.net/thomasweller/Windows-Live-Writer/44273120c499_7366/image_thumb_1.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is what I'd call a meaningful test outcome: The test actually does execute, but the method under test does not (yet) expose the expected behavior.&lt;/p&gt;
&lt;p&gt;In short: It makes sense to have empty member skeletons declared &lt;strong&gt;before&lt;/strong&gt; you write any tests. This doesn't contradict the intention of Test-driven development in any way, because it remains true that you always start with a failing test (it's just that it now 'fails' for the correct reason)...&lt;/p&gt;
&lt;p&gt;Apart from this, there's a second argument, which does not relate directly to TDD theory, but more to a C# developer's everyday working experience: A developer is more productive and makes less errors when he has decent IntelliSense support at hand. And there only can be IntelliSense if at least an empty method body exists and is accessible.&lt;/p&gt;
&lt;h4&gt;#2: "Only test the public members of a class"&lt;/h4&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;This statement may be viable for a more BDD-based approach and/or for integration-style tests, but for TDD this doesn't make sense to me: If the important functionality of a class is encapsulated in a non-public method, how could it be a problem then to write tests for this method? After all, testing (and especially TDD) is about &lt;em&gt;functionality&lt;/em&gt;, not about &lt;em&gt;visibility&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Consider, for example, the following 'production code':&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 111px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; DoSomeComplexCalculation(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg1, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg2)     &lt;br /&gt;
{     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; temp = DoSomeComplexOperation(arg1, arg2);     &lt;br /&gt;
    temp = DoAnotherComplexOperation(temp, arg1, arg2);     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; DoOneMoreComplexOperation(temp, arg1, arg2);     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;Nothing unusual here: We have a public method, which exposes some functionality to the outside world, and internally delegates the task to some helper methods. Each of them does its own part of the job, and the calling method is responsible for orchestrating the calls, combining the partial results in a meaningful way, and finally returning the end result to the caller. So far, this is standard .NET programming, often seen and quite trivial.&lt;/p&gt;
&lt;p&gt;But if you want to develop such code in a test-driven way and stick to the &lt;em&gt;Test only public members&lt;/em&gt; dogma (and of course you don't want to make everything &lt;font face="Courier New"&gt;public&lt;/font&gt;), then the only test that you could ever write would be of this form:&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 125px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DoSomeComplicatedCalculation_WhenGivenSomeValues_ReturnsExpectedResult()     &lt;br /&gt;
{     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;    int&lt;/span&gt; result = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Calculator&lt;/span&gt;().DoSomeComplicatedCalculation(1, 2);  &lt;br /&gt;
&lt;span style="color: #2b91af"&gt;    Assert&lt;/span&gt;.AreEqual(3, result, &lt;span style="color: #a31515"&gt;"Calculation does not yield the expected result."&lt;/span&gt;);     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;Let's be honest: Would that be enough for you to develop correct and robust implementations for &lt;font face="Courier New"&gt;DoSomeComplexOperation()&lt;/font&gt;, &lt;font face="Courier New"&gt;DoAnotherComplexOperation()&lt;/font&gt;, and &lt;font face="Courier New"&gt;DoOneMoreComplexOperation()&lt;/font&gt;, when these helper methods in themselves have to perform quite complicated operations? And you will be sure that you've covered all relevant corner cases? Well, then you're a better programmer than me (and possibly also better than the overwhelming majority of all the other developers out there)...&lt;/p&gt;
&lt;p&gt;Because I'm not so enlightened, I need to write quite some more test code to make sure that the production code is of high quality and (at least to my knowledge and skills) error-free. Ideally, I will do this:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Make the non-public methods accessible to the test assembly by declaring them as &lt;font face="Courier New"&gt;internal&lt;/font&gt; and giving the test assembly access rights via the &lt;font face="Courier New"&gt;InternalsVisibleTo&lt;/font&gt; attribute.&lt;/li&gt;
    &lt;li&gt;Write some &lt;em&gt;data-driven tests&lt;/em&gt; against these internal methods, covering all possible corner cases.&lt;/li&gt;
    &lt;li&gt;Write an &lt;em&gt;interaction-based test&lt;/em&gt; against the public method, to make sure that it is orchestrating the internal methods (that perform the actual calculation) as intended.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A typical test fixture of this kind then could be similar to this (using the &lt;a href="http://www.gallio.org" target="_blank"&gt;Gallio&lt;/a&gt; framework for the tests and &lt;a href="http://www.typemock.com/typemock-isolator-product3/" target="_blank"&gt;Typemock Isolator&lt;/a&gt; to verify method interactions):&lt;/p&gt;
&lt;div style="border-bottom: rgb(128,128,128) thin solid; border-left: rgb(128,128,128) thin solid; padding-bottom: 8px; padding-left: 6px; padding-right: 2px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: rgb(221,221,221); height: 1152px; color: black; font-size: 10pt; overflow: auto; border-top: rgb(128,128,128) thin solid; border-right: rgb(128,128,128) thin solid; padding-top: 8px"&gt;[&lt;span style="color: #2b91af"&gt;TestFixture&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Calculator&lt;/span&gt;))]     &lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CalculatorFixture&lt;/span&gt;     &lt;br /&gt;
{     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"DoSomeComplexOperation"&lt;/span&gt;)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(1, 2, -1)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(11, 2, 9)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(100, 100, 0)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.MaxValue, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.MinValue, -1)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.MinValue, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.MinValue, 0)]     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DoSomeComplexOperation_ReturnsExpectedResult(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg1, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg2, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; expectedResult)     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; result = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Calculator&lt;/span&gt;().DoSomeComplexOperation(arg1, arg2);     &lt;br /&gt;
        &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(expectedResult, result, &lt;span style="color: #a31515"&gt;"'DoSomeComplexOperation()' does not yield the expected result."&lt;/span&gt;);     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"DoAnotherComplexOperation"&lt;/span&gt;)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(1, 2, 3, 1)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(0, 0, 123456, 0)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(-1, 1, 3, 0)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(8, -3, 4, 1)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(1, 1, 0, 999999, ExpectedException = &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DivideByZeroException&lt;/span&gt;))]     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DoAnotherComplexOperation_ReturnsExpectedResult(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; temp, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg1, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg2, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; expectedResult)     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; result = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Calculator&lt;/span&gt;().DoAnotherComplexOperation(temp, arg1, arg2);     &lt;br /&gt;
        &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(expectedResult, result, &lt;span style="color: #a31515"&gt;"'DoAnotherComplexOperation()' does not yield the expected result."&lt;/span&gt;);     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"DoOneMoreComplexOperation"&lt;/span&gt;)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(0, 0, 0, 0)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(0, 567, -567, 567 * 2)]     &lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Row&lt;/span&gt;(1, 2, 2, 1)]     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DoOneMoreComplexOperation_ReturnsExpectedResult(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; temp, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg1, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg2, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; expectedResult)     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; result = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Calculator&lt;/span&gt;().DoOneMoreComplexOperation(temp, arg1, arg2);     &lt;br /&gt;
        &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(expectedResult, result, &lt;span style="color: #a31515"&gt;"'DoOneMoreComplexOperation()' does not yield the expected result."&lt;/span&gt;);     &lt;br /&gt;
    }     &lt;br /&gt;
&lt;br /&gt;
    [&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Isolated&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TestsOn&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"DoSomeComplicatedCalculation"&lt;/span&gt;)]     &lt;br /&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DoSomeComplicatedCalculation_VerifiesTheIntendedInteractions()     &lt;br /&gt;
    {     &lt;br /&gt;
        &lt;span style="color: #008000"&gt;// Arrange&lt;/span&gt;     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; resultFromDoSomeComplexOperation = -999;     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; resultFromDoAnotherComplexOperation = 1234;     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg1 = -1;     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg2 = 42;     &lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; calculator = &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.Fake.Instance&amp;lt;&lt;span style="color: #2b91af"&gt;Calculator&lt;/span&gt;&amp;gt;();     &lt;br /&gt;
        &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; calculator.DoSomeComplicatedCalculation(0, 0))     &lt;br /&gt;
               .CallOriginal();     &lt;br /&gt;
        &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; calculator.DoAnotherComplexOperation(0, 0, 0))     &lt;br /&gt;
               .WillReturn(resultFromDoAnotherComplexOperation);     &lt;br /&gt;
        &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.WhenCalled(() =&amp;gt; calculator.DoSomeComplexOperation(0, 0))     &lt;br /&gt;
               .WillReturn(resultFromDoSomeComplexOperation);     &lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: #008000"&gt;// Act&lt;/span&gt;     &lt;br /&gt;
        &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; result = calculator.DoSomeComplicatedCalculation(arg1, arg2);     &lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: #008000"&gt;// Assert&lt;/span&gt;     &lt;br /&gt;
        &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.Verify.WasCalledWithExactArguments(() =&amp;gt; calculator.DoSomeComplexOperation(arg1, arg2));     &lt;br /&gt;
        &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.Verify.WasCalledWithExactArguments(() =&amp;gt; calculator.DoAnotherComplexOperation(resultFromDoSomeComplexOperation, arg1, arg2));     &lt;br /&gt;
        &lt;span style="color: #2b91af"&gt;Isolate&lt;/span&gt;.Verify.WasCalledWithExactArguments(() =&amp;gt; calculator.DoOneMoreComplexOperation(resultFromDoAnotherComplexOperation, arg1, arg2));     &lt;br /&gt;
    }     &lt;br /&gt;
}&lt;/div&gt;
&lt;p&gt;- Needless to say that the above represents an ideal case, which is not always what you can fully achieve in the real (business) world, where there may be all kinds of other factors in operation (timelines, lack of resources etc.)... -&lt;/p&gt;
&lt;table width="580" cellspacing="0" cellpadding="4" border="1"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td width="580" valign="top"&gt;&lt;u&gt;A practical note&lt;/u&gt;: Because I consider access to internal members as an everyday standard in my development practice, I have a naming convention in place in my projects (test assemblies are named after the assembly they are targeting, followed by an additional&lt;font face="Courier New"&gt;&lt;font face="Arial"&gt; &lt;/font&gt;.Test&lt;/font&gt;), and I have a corresponding R# live template which generates the required &lt;font face="Courier New"&gt;InternalsVisibleTo&lt;/font&gt; statement for me.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Don't get me wrong: I'm not saying that the above necessarily is somehow preferable or better than anything else – it totally depends on the concrete project and the testing strategy that you apply to it. I'm only stating that &lt;em&gt;Testing Non-Public Members&lt;/em&gt; is a perfectly valid testing strategy in its own right. And in some situations, it might be the only one – namely, if you're consequently doing TDD (&lt;em&gt;never write a single line of code when there's no test for it!&lt;/em&gt;) and at the same time you want to keep your class' publicly accessible interface as small and clean as possible.&lt;/p&gt;
&lt;h4&gt;#3: "Never change production code only to make it testable"&lt;/h4&gt;
&lt;p&gt;Why not?&lt;/p&gt;
&lt;p&gt;As I pointed out in &lt;a href="http://geekswithblogs.net/thomasweller/archive/2010/01/27/its-the-maintenance-stupid-or-something-is-rotten-in-developerland.aspx" target="_blank"&gt;another post&lt;/a&gt;, software maintenance makes up by far the biggest portion of a software system's total lifecycle costs, and effective tests help to significantly lower these costs. So if testing can have such a massive positive impact on a companies' budget, why would I then categorially exclude this option only to stick to some theoretical principles?&lt;/p&gt;
&lt;p&gt;Of course, like with any other methodology, you have to apply it wisely. The primary goal of production code is to mimick its relating business domain as closely as possible, and it's a very bad idea to shape it after a developer's testing skills in the first place. But usually there is more than one way to skin a cat, and some of them make testing easier, while others will make it harder.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Testability&lt;/em&gt; is an important non-functional property of a codebase, so it should not be handled differently than other non-functional requirements. If there's a strong enough reason to change the code accordingly, then just do it.&lt;/p&gt;
&lt;h4&gt;#4: "TDD is a software design method"&lt;/h4&gt;
&lt;p&gt;Not really, or at least only to some extend.&lt;/p&gt;
&lt;p&gt;It's true that developing your code the TDD way will automatically lead you to well-designed code at the micro level – it's simply not possible to write meaningful tests for spaghetti-, or otherwise poorly shaped, code.&lt;/p&gt;
&lt;p&gt;But this effect doesn't apply to the system level. You need to have a clear idea of things like e.g. Class structure, Assembly partitioning, or Code layering &lt;strong&gt;before&lt;/strong&gt; you can start to write the first line of code. And to do this, you need to have good knowledge about software design (&lt;a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29" target="_blank"&gt;Design patterns&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29" target="_blank"&gt;S.O.L.I.D. principles&lt;/a&gt;, and the like...).&lt;/p&gt;
&lt;p&gt;Only then – when your draft is well shaped and generally of high quality upfront – will TDD help you to explore and hammer out the implementation details and will safely lead you down the second half of the road.&lt;/p&gt;
&lt;h4&gt;So what?&lt;/h4&gt;
&lt;p&gt;I think, these aspects are to a large extend driven by the view that TDD and software testing is considered as some kind of exotic (or at least somehow special) activity, which should not interfere with the 'real' code. This prejudice often is implicitly accepted and goes unnoticed, because it is buried deeply, at the very heart of Test-driven development. But as soon as you radically change your point of view and consider TDD/testing as the normal and preferable way of writing software (whereas writing software without tests is the exceptional case), some of the 'truths' around 'Textbook-TDD' just don't make much sense anymore...&lt;/p&gt;
&lt;table width="580" cellspacing="2" cellpadding="6" border="0" style="background-image: url(http://gwb.blob.core.windows.net/thomasweller/social/pictures/socialb-580x100.gif); background-repeat: no-repeat; background-position: -5px 50%"&gt;
    &lt;tbody&gt;
        &lt;tr style="padding-top: 4px"&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="kickit"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url="&gt;&lt;img width="88" border="0" height="22" style="position: relative; display: inline; cursor: pointer; padding-top: 6px; top: 4px" id="kick" title="Kick it!" alt="kickit" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="shoutit"&gt;&lt;a href="http://dotnetshoutout.com/Submit?url="&gt;&lt;img border="0" style="position: relative; display: inline; cursor: pointer; padding-top: 6px; top: 4px" id="shout" title="Shout it!" alt="shoutit" src="http://dotnetshoutout.com/image.axd?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="330" valign="middle" align="left"&gt;
            &lt;div id="zoneit"&gt;&lt;iframe width="150" height="20" frameborder="0" scrolling="no" style="position: relative; top: 4px" id="dzoneframe" title="Zone it!" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&amp;amp;url=&amp;amp;title="&gt;&lt;/iframe&gt;&lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="middle" colspan="3"&gt;&lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="delicious" title="Bookmark this on Delicious." onclick="setBookmark('delicious');" alt="delicious" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/delicious-32x32.png" /&gt; &lt;a id="fbshare" href="http://www.facebook.com/sharer.php"&gt;&lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; left: 2px" id="facebook" title="Share this on Facebook." alt="facebook" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/facebook-48x48.png" /&gt;&lt;/a&gt; &lt;img width="34" border="0" height="34" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="digg" title="Digg this." onclick="setBookmark('digg');" alt="digg" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/digg-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="reddit" title="Reddit this." onclick="setBookmark('reddit');" alt="reddit" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/reddit-48x48.png" /&gt; &lt;img width="34" border="0" height="34" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="linkedin" title="Share this on LinkedIn." onclick="setBookmark('linkedin');" alt="linkedin" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/linkedin-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="stumbleupon" title="Stumble!" onclick="setBookmark('stumbleupon');" alt="stumbleupon" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/stumbleupon-48x48.png" /&gt; &lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; padding-top: 1px; left: 2px" id="technorati" title="Add this to Technorati." onclick="setBookmark('technorati')" alt="technorati" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/technorati-48x48.png" /&gt; &lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; margin: 1px 0px 0px 1px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="mrwong" title="Bookmark this on Mister Wong." onclick="setBookmark('mrwong');" alt="mrwong" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/mrwong-32x32.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="yahoobkm" title="Bookmark this on Yahoo." onclick="setBookmark('yahoobkm')" alt="yahoo" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/yahoo-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="googlebkm" title="Bookmark this on Google." onclick="setBookmark('googlebkm');" alt="google-48x48" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/google-48x48.png" /&gt; &lt;img width="33" border="0" height="33" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="twitter" title="Tweet this (with bit.ly URL)." onclick="BitlyClient.shorten(document.location, 'BitlyCB.shortenResponse');" alt="twitter" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/twitter-48x48.png" /&gt; &lt;img width="31" border="0" height="31" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="mail" title="Send a link via E-Mail." onclick="mailpage();" alt="email" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/email-32x32.png" /&gt; &lt;img width="32" border="0" height="32" style="position: relative; border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; cursor: pointer; left: 2px" id="bookmark" title="Bookmark this page in your browser." onclick="bookmarkInBrowser();" alt="favorites" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/favorites-star-128x128.png" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/147500.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2011/10/31/some-myths-of-textbook-tdd-and-why-they-are-wrong.aspx</guid>
            <pubDate>Mon, 31 Oct 2011 12:44:06 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/147500.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2011/10/31/some-myths-of-textbook-tdd-and-why-they-are-wrong.aspx#feedback</comments>
            <slash:comments>18</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/147500.aspx</wfw:commentRss>
        </item>
        <item>
            <title>An introductory presentation about testing with MSTest, Visual Studio, and Team Foundation Server 2010</title>
            <category>Automation</category>
            <category>Unit Testing/TDD</category>
            <category>Open Source</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2011/02/21/an-introductory-presentation-about-testing-with-mstest-visual-studio-and.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2011/02/21/an-introductory-presentation-about-testing-with-mstest-visual-studio-and.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2011/02/21/an-introductory-presentation-about-testing-with-mstest-visual-studio-and.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;While it was very quiet here on my blog during the last months, this was not at all true for the rest of my professional life. The simple story is that I was too busy to find the time for authoring blog posts (and you might see from my previous ones that they’re usually not of the ‘&lt;em&gt;Hey, I’m currently reading X’&lt;/em&gt; or ‘&lt;em&gt;I’m currently thinking about Y’&lt;/em&gt; kind…).&lt;/p&gt;
&lt;p&gt;Anyway. Among the things I did during the last months were setting up a TFS environment (2010) and introducing a development team to the MSTest framework (aka. &lt;em&gt;Visual Studio Unit Testing&lt;/em&gt;), some additional tools (e.g. &lt;a target="_blank" href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;, &lt;a target="_blank" href="http://visualstudiogallery.msdn.microsoft.com/22c07bda-ffc9-479a-9766-bfd6ccacabd4/"&gt;Moles&lt;/a&gt;, &lt;a target="_blank" href="http://white.codeplex.com/"&gt;White&lt;/a&gt;),  how this is supported in Visual Studio, and how it integrates into the broader context of the then new TFS environment.&lt;/p&gt;
&lt;p&gt;After wiping out all the stuff which was directly related to my former customer and reviewing/extending the Speaker notes, I thought I share this presentation (via &lt;a target="_blank" href="http://white.codeplex.com/"&gt;Slideshare&lt;/a&gt;) with the rest of the world. Hopefully it can be useful to someone else out there…&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.slideshare.net/th-weller/introduction-to-testing-with-mstest-visual-studio-and-team-foundation-server-2010" title="Introduction to testing with MSTest, Visual Studio, and Team Foundation Server 2010"&gt;&lt;font size="2"&gt;&lt;strong&gt;Introduction to testing with MSTest, Visual Studio, and Team Foundation Server 2010&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div id="__ss_7001350"&gt;&lt;object width="425" height="355" id="__sse7001350"&gt;
&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=introductiontomstestandtfs2010-110221124923-phpapp01&amp;amp;stripped_title=introduction-to-testing-with-mstest-visual-studio-and-team-foundation-server-2010&amp;amp;userName=th-weller" /&gt;
&lt;param name="allowFullScreen" value="true" /&gt;
&lt;param name="allowScriptAccess" value="always" /&gt;&lt;embed width="570" height="476" name="__sse7001350" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=introductiontomstestandtfs2010-110221124923-phpapp01&amp;amp;stripped_title=introduction-to-testing-with-mstest-visual-studio-and-team-foundation-server-2010&amp;amp;userName=th-weller" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;div style="padding: 5px 0px 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/th-weller"&gt;Thomas Weller&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Be sure to also check out the slide notes (either by viewing the presentation directly on Slideshare or - even better - by downloading it). They contain quite some additional information, hints, and (in my opinion) best practices.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table width="580" cellspacing="2" cellpadding="6" border="0" style="background-image: url(&amp;quot;http://gwb.blob.core.windows.net/thomasweller/social/pictures/socialb-580x100.gif&amp;quot;); background-repeat: no-repeat; background-position: -5px 50%;"&gt;
    &lt;tbody&gt;
        &lt;tr style="padding-top: 4px;"&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="kickit"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url="&gt;&lt;img width="88" border="0" height="22" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=" alt="kickit" title="Kick it!" id="kick" style="position: relative; display: inline; top: 4px; cursor: pointer; padding-top: 6px;" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="shoutit"&gt;&lt;a href="http://dotnetshoutout.com/Submit?url="&gt;&lt;img border="0" style="position: relative; display: inline; top: 4px; cursor: pointer; padding-top: 6px;" id="shout" title="Shout it!" alt="shoutit" src="http://dotnetshoutout.com/image.axd?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="330" valign="middle" align="left"&gt;
            &lt;div id="zoneit"&gt;&lt;iframe width="150" height="20" frameborder="0" scrolling="no" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&amp;amp;url=&amp;amp;title=" title="Zone it!" id="dzoneframe" style="position: relative; top: 4px;"&gt;&lt;/iframe&gt;&lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="middle" colspan="3"&gt;&lt;img width="32" border="0" height="32" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/delicious-32x32.png" alt="delicious" onclick="setBookmark('delicious');" title="Bookmark this on Delicious." id="delicious" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;a href="http://www.facebook.com/sharer.php" id="fbshare"&gt;&lt;img width="33" border="0" height="33" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/facebook-48x48.png" alt="facebook" title="Share this on Facebook." id="facebook" style="position: relative; border-width: 0px; display: inline; left: 2px;" /&gt;&lt;/a&gt; &lt;img width="34" border="0" height="34" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/digg-48x48.png" alt="digg" onclick="setBookmark('digg');" title="Digg this." id="digg" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" border="0" height="33" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/reddit-48x48.png" alt="reddit" onclick="setBookmark('reddit');" title="Reddit this." id="reddit" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="34" border="0" height="34" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/linkedin-48x48.png" alt="linkedin" onclick="setBookmark('linkedin');" title="Share this on LinkedIn." id="linkedin" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" border="0" height="33" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/stumbleupon-48x48.png" alt="stumbleupon" onclick="setBookmark('stumbleupon');" title="Stumble!" id="stumbleupon" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="32" border="0" height="32" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/technorati-48x48.png" alt="technorati" onclick="setBookmark('technorati')" title="Add this to Technorati." id="technorati" style="position: relative; border-width: 0px; display: inline; cursor: pointer; padding-top: 1px; left: 2px;" /&gt; &lt;img width="32" border="0" height="32" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/mrwong-32x32.png" alt="mrwong" onclick="setBookmark('mrwong');" title="Bookmark this on Mister Wong." id="mrwong" style="position: relative; border-width: 0px; margin: 1px 0px 0px 1px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" border="0" height="33" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/yahoo-48x48.png" alt="yahoo" onclick="setBookmark('yahoobkm')" title="Bookmark this on Yahoo." id="yahoobkm" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" border="0" height="33" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/google-48x48.png" alt="google-48x48" onclick="setBookmark('googlebkm');" title="Bookmark this on Google." id="googlebkm" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" border="0" height="33" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/twitter-48x48.png" alt="twitter" onclick="BitlyClient.shorten(document.location, 'BitlyCB.shortenResponse');" title="Tweet this (with bit.ly URL)." id="twitter" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="31" border="0" height="31" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/email-32x32.png" alt="email" onclick="mailpage();" title="Send a link via E-Mail." id="mail" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="32" border="0" height="32" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/favorites-star-128x128.png" alt="favorites" onclick="bookmarkInBrowser();" title="Bookmark this page in your browser." id="bookmark" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/144036.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2011/02/21/an-introductory-presentation-about-testing-with-mstest-visual-studio-and.aspx</guid>
            <pubDate>Mon, 21 Feb 2011 19:05:52 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/144036.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2011/02/21/an-introductory-presentation-about-testing-with-mstest-visual-studio-and.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/144036.aspx</wfw:commentRss>
        </item>
        <item>
            <title>dotCover - a new kid on the (development) block</title>
            <category>Unit Testing/TDD</category>
            <category>Automation</category>
            <category>Code Coverage</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2010/07/16/dotcover---a-new-kid-on-the-development-block.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2010/07/16/dotcover---a-new-kid-on-the-development-block.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2010/07/16/dotcover---a-new-kid-on-the-development-block.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;These days, JetBrains (the manufacturer of &lt;a target="_blank" href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt; (R#)) released the beta version of a new code coverage tool – &lt;a target="_blank" href="http://www.jetbrains.com/dotcover"&gt;dotCover&lt;/a&gt;. Because I’m a big fan of the R# add-in, I was particularly curious about having a first look at the newest JetBrains child. Notably, I wanted to see how it would take advantage of its deep R#/VS integration to make code coverage an integral part of a developer’s working experience. Here are my first impressions about it…&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Note&lt;/u&gt;&lt;/strong&gt;: Because I’m using &lt;a target="_blank" href="http://www.ncover.com/"&gt;NCover&lt;/a&gt; for Code coverage analysis at the moment, I cannot help comparing these two tools, although this might not be totally appropriate: dotCover is designed to deeply integrate with R# and Visual Studio, whereas NCover is a stand-alone application. Also, NCover is a mature and feature-rich application, whereas dotCover is in its early infancy…&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Some useful related resources (links to website, documentation material and some videos) can be found in my &lt;a href="http://blog.thomas-weller.de/archive/2010/02/27/a-delicious-toolbox.aspx"&gt;toolbox on Delicious&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;dotCover - &lt;a href="http://delicious.com/thomasweller/toolbox+dotcover"&gt;http://delicious.com/thomasweller/toolbox+dotcover&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;NCover - &lt;a href="http://delicious.com/thomasweller/toolbox+ncover"&gt;http://delicious.com/thomasweller/toolbox+ncover&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;or both - &lt;a href="http://delicious.com/thomasweller/toolbox+code-coverage"&gt;http://delicious.com/thomasweller/toolbox+code-coverage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1&gt; About Code Coverage&lt;/h1&gt;
&lt;p&gt;Much has been written about Code Coverage and about what it can do and what not – see for example &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Code_coverage"&gt;here&lt;/a&gt; and &lt;a target="_blank" href="http://www.slideshare.net/ravreddy/code-coverage?from=embed"&gt;here&lt;/a&gt;. The bottom line is: The single useful aspect of Code Coverage is that it shows you which parts of your production code are NOT covered by any tests, and thus gives you a basis to decide upon those areas: You simply may have overlooked it, or you may have made the explicit decision to not test it.&lt;/p&gt;
&lt;p&gt;And this is exactly what I’m interested in when writing tests - be it after the fact (i.e. covering a pre-existing codebase with tests) or be it when authoring new code in a TDD process: I want to quickly see which parts of the production code are covered with tests, and I want to be able to quickly jump to and inspect code which is not. In short: It’s &lt;strong&gt;productivity&lt;/strong&gt; what I’m looking for in the first place. In-depth information - like it is provided by NCover - is part of a broader picture that becomes important when deeply analyzing an entire codebase or monitoring historical trend data. But for now, let’s exclusively focus on the coding process itself…&lt;/p&gt;
&lt;h1&gt;Running tests with coverage&lt;/h1&gt;
&lt;p&gt;DotCover will add a new item to the familiar R# menu, which allows you to run tests with coverage just like you would run ‘normal’ tests from R#:&lt;/p&gt;
&lt;p&gt;&lt;img width="343" height="165" border="0" align="left" src="http://gwb.blob.core.windows.net/thomasweller/WindowsLiveWriter/dotCoveranewkidonthedevelopmentblock_66FB/RunningFromReSharper_3.gif" alt="RunningFromReSharper" title="RunningFromReSharper" style="border: 0px none; margin: 5px 0px 0px; display: inline;" /&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;      &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;DotCover also adds a new tab to the R# &lt;em&gt;Unit Test Sessions&lt;/em&gt; tool window, showing the results of the current coverage run:&lt;/p&gt;
&lt;p&gt;&lt;img width="585" height="366" border="0" align="left" src="http://gwb.blob.core.windows.net/thomasweller/WindowsLiveWriter/dotCoveranewkidonthedevelopmentblock_66FB/CoverageToolWindow_3.gif" alt="CoverageToolWindow" title="CoverageToolWindow" style="border-width: 0px; margin: 5px 0px 0px; display: inline;" /&gt;&lt;/p&gt;
&lt;p&gt; From there, you can directly navigate to the code under test via double click, which will be highlighted in red and green according to the measured test coverage:&lt;/p&gt;
&lt;p&gt;&lt;img width="558" height="149" border="0" align="left" src="http://gwb.blob.core.windows.net/thomasweller/WindowsLiveWriter/dotCoveranewkidonthedevelopmentblock_66FB/HighlightCodeAreas_3.gif" alt="HighlightCodeAreas" title="HighlightCodeAreas" style="border-width: 0px; display: inline; margin-left: 0px; margin-right: 0px;" /&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;  &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt; &lt;/div&gt;
&lt;h1&gt;Navigating from production code to test code&lt;/h1&gt;
&lt;p&gt;It is also possible to browse your&lt;em&gt; test code &amp;lt;-&amp;gt; production code&lt;/em&gt; connections from the other direction. After a coverage run, dotCover will show you which tests are operating on a selected code line when right-clicking it and choosing &lt;em&gt;Show Covering Tests&lt;/em&gt; form the context menu:&lt;/p&gt;
&lt;p&gt;&lt;img width="374" height="78" border="0" align="left" src="http://gwb.blob.core.windows.net/thomasweller/WindowsLiveWriter/dotCoveranewkidonthedevelopmentblock_66FB/ShowCoveringTests_3.gif" alt="ShowCoveringTests" title="ShowCoveringTests" style="border: 0px none; margin: 5px 0px 0px; display: inline;" /&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;This will open up a popup window like the one below, giving you a list of relevant tests:&lt;/p&gt;
&lt;p&gt;&lt;img width="591" height="203" border="0" align="left" src="http://gwb.blob.core.windows.net/thomasweller/WindowsLiveWriter/dotCoveranewkidonthedevelopmentblock_66FB/ListOfCoveringTests_3.gif" alt="ListOfCoveringTests" title="ListOfCoveringTests" style="border: 0px none; margin: 0px 100px 0px 0px; display: inline;" /&gt;&lt;/p&gt;
&lt;div&gt; &lt;/div&gt;
&lt;h1&gt;Summary&lt;/h1&gt;
&lt;p&gt;The dotCover tool makes code coverage analysis as simple and fast as it was never before. It doesn’t provide all the sophisticated features that NCover has (e.g. branch coverage or trend analysis, to name just two…), but instead it integrates deeply with your coding process and lets you browse and navigate between test code and production code inside VS with only one or two mouse clicks while highlighting the covered/uncovered code areas. Unlike NCover, there’s no need to switch between different applications and to figure out complicated sets of options and/or command lines. Especially when used with a consequent TDD process (like the one I described &lt;a target="_blank" href="http://geekswithblogs.net/thomasweller/archive/2010/04/17/down-these-red-green-refactor-streets-a-tdd-developer-must-gohellip.aspx"&gt;here&lt;/a&gt; in some detail), dotCover is a great help in writing tests and can strongly boost a developer’s productivity.&lt;/p&gt;
&lt;p&gt;That’s the pro side of the coin. The contra for now is, that there is not yet any automation support – meaning that it’s not yet possible to use dotCover coverage reports from a &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Continuous_integration"&gt;Continuous Integration&lt;/a&gt; process. This is where NCover is quite ahead at the moment: It allows you to generate nice and detailed coverage reports and data from the command line or via MSBuild/NAnt tasks and thus can seamlessly be integrated with a CI tool like e.g. &lt;a target="_blank" href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl.NET&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;DotCover does a great job on the development side of things, because it integrates perfectly with R# and VS. From a developer’s point of view, code coverage never was easier. This part of the picture is really impressing IMHO. (And as a side note: Although the current version is in a quite early beta state, I found it to be impressingly stable…)&lt;/p&gt;
&lt;p&gt;However, there is not yet any automation support (a command-line interface and probably some MSBuild and NAnt tasks), so dotCover cannot be integrated with any Continuous Integration tool at the moment, which (at least for me) means that it’s not yet ready for production regarding the current feature set. But as said before, dotCover is in an early beta, and these features are announced for the final 1.0 version. Like the JetBrains people put it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;dotCover is still in its infancy and we’ve got a lot planned in terms of features and functionality. Quite a few people have asked whether it will support running coverage reports from a console, which is important for continuous integration. dotCover will support running from a console with some basic functionality, and we have plans to include specific features for CI processes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So let’s just look forward to the things to come…&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table width="580" cellspacing="2" cellpadding="6" border="0" style="background-image: url(&amp;quot;http://gwb.blob.core.windows.net/thomasweller/social/pictures/socialb-580x100.gif&amp;quot;); background-repeat: no-repeat; background-position: -5px 50%;"&gt;
    &lt;tbody&gt;
        &lt;tr style="padding-top: 4px;"&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="kickit"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url="&gt;&lt;img width="88" height="22" border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=" alt="kickit" title="Kick it!" id="kick" style="position: relative; display: inline; top: 4px; cursor: pointer; padding-top: 6px;" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="shoutit"&gt;&lt;a href="http://dotnetshoutout.com/Submit?url="&gt;&lt;img border="0" src="http://dotnetshoutout.com/image.axd?url=" alt="shoutit" title="Shout it!" id="shout" style="position: relative; display: inline; top: 4px; cursor: pointer; padding-top: 6px;" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="330" valign="middle" align="left"&gt;
            &lt;div id="zoneit"&gt;&lt;iframe width="150" height="20" frameborder="0" scrolling="no" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&amp;amp;url=&amp;amp;title=" title="Zone it!" id="dzoneframe" style="position: relative; top: 4px;"&gt;&lt;/iframe&gt;&lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="middle" colspan="3"&gt;&lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/delicious-32x32.png" alt="delicious" onclick="setBookmark('delicious');" title="Bookmark this on Delicious." id="delicious" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;a href="http://www.facebook.com/sharer.php" id="fbshare"&gt;&lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/facebook-48x48.png" alt="facebook" title="Share this on Facebook." id="facebook" style="position: relative; border-width: 0px; display: inline; left: 2px;" /&gt;&lt;/a&gt; &lt;img width="34" height="34" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/digg-48x48.png" alt="digg" onclick="setBookmark('digg');" title="Digg this." id="digg" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/reddit-48x48.png" alt="reddit" onclick="setBookmark('reddit');" title="Reddit this." id="reddit" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="34" height="34" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/linkedin-48x48.png" alt="linkedin" onclick="setBookmark('linkedin');" title="Share this on LinkedIn." id="linkedin" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/stumbleupon-48x48.png" alt="stumbleupon" onclick="setBookmark('stumbleupon');" title="Stumble!" id="stumbleupon" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/technorati-48x48.png" alt="technorati" onclick="setBookmark('technorati')" title="Add this to Technorati." id="technorati" style="position: relative; border-width: 0px; display: inline; cursor: pointer; padding-top: 1px; left: 2px;" /&gt; &lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/mrwong-32x32.png" alt="mrwong" onclick="setBookmark('mrwong');" title="Bookmark this on Mister Wong." id="mrwong" style="position: relative; border-width: 0px; margin: 1px 0px 0px 1px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/yahoo-48x48.png" alt="yahoo" onclick="setBookmark('yahoobkm')" title="Bookmark this on Yahoo." id="yahoobkm" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/google-48x48.png" alt="google-48x48" onclick="setBookmark('googlebkm');" title="Bookmark this on Google." id="googlebkm" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/twitter-48x48.png" alt="twitter" onclick="BitlyClient.shorten(document.location, 'BitlyCB.shortenResponse');" title="Tweet this (with bit.ly URL)." id="twitter" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="31" height="31" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/email-32x32.png" alt="email" onclick="mailpage();" title="Send a link via E-Mail." id="mail" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/favorites-star-128x128.png" alt="favorites" onclick="bookmarkInBrowser();" title="Bookmark this page in your browser." id="bookmark" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt; &lt;/p&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/140955.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2010/07/16/dotcover---a-new-kid-on-the-development-block.aspx</guid>
            <pubDate>Fri, 16 Jul 2010 09:34:38 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/140955.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2010/07/16/dotcover---a-new-kid-on-the-development-block.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/140955.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Mocking the Unmockable: Using Microsoft Moles with Gallio</title>
            <category>Automation</category>
            <category>Unit Testing/TDD</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2010/04/28/mocking-the-unmockable-using-microsoft-moles-with-gallio.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2010/04/28/mocking-the-unmockable-using-microsoft-moles-with-gallio.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2010/04/28/mocking-the-unmockable-using-microsoft-moles-with-gallio.aspx&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;
&lt;p&gt;&lt;u&gt;Update 29/04/10&lt;/u&gt;:&lt;/p&gt;
&lt;p&gt;In contrary to what I initially stated in this post, Moles is not  only available as part of the Pex framework, but also &lt;a href="http://visualstudiogallery.msdn.microsoft.com/en-us/b3b41648-1c21-471f-a2b0-f76d8fb932ee"&gt;stand-alone  on Visual Studio Gallery&lt;/a&gt;, and this is completely free (no MSDN  subscription required). - Thanks to Peli for the correction...&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Usual opensource mocking frameworks (like e.g. &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; or &lt;a href="http://ayende.com/projects/rhino-mocks.aspx"&gt;Rhino.Mocks&lt;/a&gt;) can mock only interfaces and virtual methods. In contrary to that, Microsoft’s &lt;a href="http://research.microsoft.com/en-us/projects/moles/"&gt;Moles&lt;/a&gt; framework can ‘mock’ virtually anything, in that it uses runtime instrumentation to inject callbacks in the method MSIL bodies of the moled methods. Therefore, it is possible to detour any .NET method, including non-virtual/static methods in sealed types. This can be extremely helpful when dealing e.g. with code that calls into the .NET framework, some third-party or legacy stuff etc…&lt;/p&gt;
&lt;p&gt;Some useful collected resources (links to website, documentation material and some videos) can be found in my &lt;a href="http://blog.thomas-weller.de/archive/2010/02/27/a-delicious-toolbox.aspx"&gt;toolbox on Delicious&lt;/a&gt; under this link:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://delicious.com/thomasweller/toolbox+moles"&gt;http://delicious.com/thomasweller/toolbox+moles&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;A Gallio extension for Moles&lt;/h1&gt;
&lt;p&gt;Originally, Moles is a part of Microsoft’s &lt;a href="http://research.microsoft.com/en-us/projects/pex/"&gt;Pex&lt;/a&gt; framework and thus integrates best with Visual Studio Unit Tests (MSTest). However, the Moles sample download contains some additional assemblies to also support other unit test frameworks. They provide a &lt;font face="Courier New"&gt;Moled&lt;/font&gt; attribute to ease the usage of mole types with the respective framework (there are extensions for &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt;, &lt;a href="http://xunit.codeplex.com/"&gt;xUnit.net&lt;/a&gt; and MbUnit v2 included with the samples). As there is no such extension for the &lt;a href="http://www.gallio.org"&gt;Gallio&lt;/a&gt; platform, I did the few required lines myself – the resulting &lt;font face="Courier New"&gt;Gallio.Moles.dll&lt;/font&gt; is included with the &lt;a href="http://rapidshare.com/files/381136693/Gallio.Moles.zip"&gt;sample download&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With this little assembly in place, it is possible to use Moles with Gallio like that:&lt;/p&gt;
&lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt;"&gt;&lt;code&gt; &lt;/code&gt;
&lt;pre style="margin: 0px;"&gt;
[&lt;span style="color: rgb(43, 145, 175);"&gt;Test&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;Moled&lt;/span&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;void&lt;/span&gt; SomeTest()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;
    ...&lt;/pre&gt;
&lt;/div&gt;
&lt;h1&gt;What you can do with it&lt;/h1&gt;
&lt;p&gt;Moles can be very helpful, if you need to ‘mock’ something other than a virtual or interface-implementing method. This might be the case when dealing with some third-party component, legacy code, or if you want to ‘mock’ the .NET framework itself.&lt;/p&gt;
&lt;p&gt;Generally, you need to announce each moled type that you want to use in a test with the &lt;font face="Courier New"&gt;MoledType&lt;/font&gt; attribute on assembly level. For example:&lt;/p&gt;
&lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt;"&gt;&lt;code&gt;     &lt;/code&gt;
&lt;pre style="margin: 0px;"&gt;
[&lt;span style="color: blue;"&gt;assembly&lt;/span&gt;: &lt;span style="color: rgb(43, 145, 175);"&gt;MoledType&lt;/span&gt;(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(System.IO.&lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;))]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Below are some typical use cases for Moles. For a more detailed overview (incl. naming conventions and an instruction on how to create the required moles assemblies), please refer to the reference material above. &lt;/p&gt;
&lt;ol&gt;
    &lt;h2&gt;Detouring the .NET framework&lt;/h2&gt;
    &lt;p&gt;Imagine that you want to test a method similar to the one below, which internally calls some framework method: &lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt;"&gt;&lt;code&gt;     &lt;/code&gt;
    &lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ReadFileContent(&lt;span style="color: blue;"&gt;string&lt;/span&gt; fileName)&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
{&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;this&lt;/span&gt;.FileContent = System.IO.&lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;.ReadAllText(fileName);&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
}&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt;Using a mole, you would replace the call to the &lt;font face="Courier New"&gt;File.ReadAllText(string)&lt;/font&gt; method with a runtime delegate like so:&lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt; overflow: scroll;"&gt;&lt;code&gt;       &lt;/code&gt;
    &lt;pre style="margin: 0px;"&gt;
[&lt;span style="color: rgb(43, 145, 175);"&gt;Test&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;Moled&lt;/span&gt;]&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
[&lt;span style="color: rgb(43, 145, 175);"&gt;Description&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"This 'mocks' the System.IO.File class with a custom delegate."&lt;/span&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;void&lt;/span&gt; ReadFileContentWithMoles()&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
{&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;// arrange ('mock' the FileSystem with a delegate)&lt;/span&gt;&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    System.IO.Moles.&lt;span style="color: rgb(43, 145, 175);"&gt;MFile&lt;/span&gt;.ReadAllTextString = &lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
        (fname =&amp;gt; fname == FileName ? FileContent : &lt;span style="color: rgb(163, 21, 21);"&gt;"WrongFileName"&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;// act &lt;/span&gt;&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;var&lt;/span&gt; testTarget = &lt;span style="color: blue;"&gt;new&lt;/span&gt; TestTarget.&lt;span style="color: rgb(43, 145, 175);"&gt;TestTarget&lt;/span&gt;();&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    testTarget.ReadFileContent(FileName);&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: green;"&gt;// assert &lt;/span&gt;&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.AreEqual(FileContent, testTarget.FileContent);&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
}&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt; &lt;/p&gt;
    &lt;h2&gt;Detouring static methods and/or classes&lt;/h2&gt;
    &lt;p&gt;A static method like the below…&lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt;"&gt;&lt;code&gt;       &lt;/code&gt;
    &lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; StaticMethod(&lt;span style="color: blue;"&gt;int&lt;/span&gt; x, &lt;span style="color: blue;"&gt;int&lt;/span&gt; y)&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&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;string&lt;/span&gt;.Format(&lt;span style="color: rgb(163, 21, 21);"&gt;"{0}{1}"&lt;/span&gt;, x, y);&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
}&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt;… can be ‘mocked’ with the following:&lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt;"&gt;&lt;code&gt;       &lt;/code&gt;
    &lt;pre style="margin: 0px;"&gt;
[&lt;span style="color: rgb(43, 145, 175);"&gt;Test&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;Moled&lt;/span&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;void&lt;/span&gt; StaticMethodWithMoles()&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
{&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: rgb(43, 145, 175);"&gt;MStaticClass&lt;/span&gt;.StaticMethodInt32Int32 = ((x, y) =&amp;gt; &lt;span style="color: rgb(163, 21, 21);"&gt;"uups"&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;var&lt;/span&gt; result = &lt;span style="color: rgb(43, 145, 175);"&gt;StaticClass&lt;/span&gt;.StaticMethod(1, 2);&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: rgb(163, 21, 21);"&gt;"uups"&lt;/span&gt;, result);&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
}&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt; &lt;/p&gt;
    &lt;h2&gt;Detouring constructors&lt;/h2&gt;
    &lt;p&gt;You can do this delegate thing even with a class’ constructor. The syntax for this is not all  too intuitive, because you have to setup the internal state of the mole, but generally it works like a charm. For example, to replace this c’tor…&lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt;"&gt;&lt;code&gt;       &lt;/code&gt;
    &lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ClassWithCtor&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;public&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; Value { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;set&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;public&lt;/span&gt; ClassWithCtor(&lt;span style="color: blue;"&gt;int&lt;/span&gt; someValue)&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    {&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Value = someValue;&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    }&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
}&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt;… you would do the following:&lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt; overflow: scroll;"&gt;&lt;code&gt;       &lt;/code&gt;
    &lt;pre style="margin: 0px;"&gt;
[&lt;span style="color: rgb(43, 145, 175);"&gt;Test&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;Moled&lt;/span&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;void&lt;/span&gt; ConstructorTestWithMoles()&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
{&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: rgb(43, 145, 175);"&gt;MClassWithCtor&lt;/span&gt;.ConstructorInt32 =&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
           ((@class, @value) =&amp;gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;MClassWithCtor&lt;/span&gt;(@class) {ValueGet = () =&amp;gt; 99});&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;var&lt;/span&gt; classWithCtor = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ClassWithCtor&lt;/span&gt;(3);&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.AreEqual(99, classWithCtor.Value);&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
}&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt; &lt;/p&gt;
    &lt;h2&gt;Detouring abstract base classes&lt;/h2&gt;
    &lt;p&gt;You can also use this approach to ‘mock’ abstract base classes of a class that you call in your test. Assumed that you have something like that:&lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt; overflow: scroll;"&gt;&lt;code&gt;       &lt;/code&gt;
    &lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;AbstractBaseClass&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;public&lt;/span&gt; &lt;span style="color: blue;"&gt;virtual&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; SaySomething()&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    {&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
        &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: rgb(163, 21, 21);"&gt;"Hello from base."&lt;/span&gt;;&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    }&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&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;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ChildClass&lt;/span&gt; : &lt;span style="color: rgb(43, 145, 175);"&gt;AbstractBaseClass&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;public&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; SaySomething()&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&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;string&lt;/span&gt;.Format(&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: rgb(163, 21, 21);"&gt;"Hello from child. Base says: '{0}'"&lt;/span&gt;, &lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
            &lt;span style="color: blue;"&gt;base&lt;/span&gt;.SaySomething());&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    }&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
}&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt;Then you would set up the child’s underlying base class like this:&lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt; overflow: scroll;"&gt;&lt;code&gt;       &lt;/code&gt;
    &lt;pre style="margin: 0px;"&gt;
[&lt;span style="color: rgb(43, 145, 175);"&gt;Test&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;Moled&lt;/span&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;void&lt;/span&gt; AbstractBaseClassTestWithMoles()&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
{&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: rgb(43, 145, 175);"&gt;ChildClass&lt;/span&gt; child = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ChildClass&lt;/span&gt;();&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;MAbstractBaseClass&lt;/span&gt;(child)&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
        {&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
                SaySomething = () =&amp;gt; &lt;span style="color: rgb(163, 21, 21);"&gt;"Leave me alone!"&lt;/span&gt;&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
        }&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
        .InstanceBehavior = &lt;span style="color: rgb(43, 145, 175);"&gt;MoleBehaviors&lt;/span&gt;.Fallthrough;&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: blue;"&gt;var&lt;/span&gt; hello = child.SaySomething();&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
 &lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
    &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: rgb(163, 21, 21);"&gt;"Hello from child. Base says: 'Leave me alone!'"&lt;/span&gt;, hello);&lt;/pre&gt;
    &lt;pre style="margin: 0px;"&gt;
}&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt;Setting the moles behavior to a value of  &lt;font face="Courier New"&gt;MoleBehaviors.Fallthrough&lt;/font&gt; causes the ‘original’ method to be called if a respective delegate is not provided explicitly – here it causes the &lt;font face="Courier New"&gt;ChildClass’&lt;/font&gt; override of the &lt;font face="Courier New"&gt;SaySomething()&lt;/font&gt; method to be called.&lt;/p&gt;
    &lt;p&gt;There are some more possible scenarios, where the Moles framework could be of much help (e.g. it’s also possible to detour interface implementations like&lt;font face="Courier New"&gt; IEnumerable&amp;lt;T&amp;gt;&lt;/font&gt; and such…). One other possibility that comes to my mind (because I’m currently dealing with that), is to replace calls from repository classes to the &lt;a href="http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework"&gt;ADO.NET Entity Framework&lt;/a&gt; O/R mapper with delegates to isolate the repository classes from the underlying database, which otherwise would not be possible…&lt;/p&gt;
    &lt;h1&gt;Usage&lt;/h1&gt;
    &lt;p&gt;Since Moles relies on runtime instrumentation, mole types must be run under the Pex profiler. This only works from inside Visual Studio if you write your tests with MSTest (Visual Studio Unit Test). While other unit test frameworks generally can be used with Moles, they require the respective tests to be run via command line, executed through the&lt;font face="Courier New"&gt; moles.runner.exe&lt;/font&gt; tool. A typical test execution would be similar to this:&lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt; overflow: scroll;"&gt;&lt;code&gt;moles.runner.exe &amp;lt;mytests.dll&amp;gt; /runner:&amp;lt;myframework.console.exe&amp;gt; /args:/&amp;lt;myargs&amp;gt; &lt;/code&gt;&lt;/div&gt;
    &lt;p&gt;So, the moled test can be run through tools like &lt;a href="http://www.ncover.com"&gt;NCover&lt;/a&gt; or a scripting tool like &lt;a href="http://msdn.microsoft.com/en-us/library/wea2sca5.aspx"&gt;MSBuild&lt;/a&gt; (which makes them easy to run in a Continuous Integration environment), but they are somewhat unhandy to run in the usual TDD workflow (which I described in some detail &lt;a href="http://geekswithblogs.net/thomasweller/archive/2010/04/17/down-these-red-green-refactor-streets-a-tdd-developer-must-gohellip.aspx"&gt;here&lt;/a&gt;). To make this a bit more fluent, I wrote a &lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt; live template to generate the respective command line for the test (it is also included in the sample download – &lt;font face="Courier New"&gt;moled_cmd.xml&lt;/font&gt;). - This is just a quick-and-dirty ‘solution’. Maybe it makes sense to write an extra Gallio adapter plugin (similar to the many others that are already provided) and include it with the Gallio download package, if  there’s sufficient demand for it.&lt;/p&gt;
    &lt;p&gt;As of now, the only way to run tests with the Moles framework from within Visual Studio is by using them with MSTest. From the command line, anything with a managed console runner can be used (provided that the appropriate extension is in place)…&lt;/p&gt;
    &lt;p&gt;A typical Gallio/Moles command line (as generated by the mentioned R#-template) looks like that:&lt;/p&gt;
    &lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: 10pt; overflow: scroll;"&gt;&lt;code&gt;"%ProgramFiles%\Microsoft Moles\bin\moles.runner.exe" /runner:"%ProgramFiles%\Gallio\bin\Gallio.Echo.exe" "Gallio.Moles.Demo.dll" /args:/r:IsolatedAppDomain /args:/filter:"ExactType:TestFixture and Member:ReadFileContentWithMoles" &lt;/code&gt;&lt;/div&gt;
    &lt;p&gt;-- Note: When using the command line with Echo (Gallio’s console runner), be sure to always include the &lt;font face="Courier New"&gt;IsolatedAppDomain option&lt;/font&gt;, otherwise the tests won’t use the instrumentation callbacks! --&lt;/p&gt;
    &lt;h1&gt;License issues&lt;/h1&gt;
    &lt;p&gt;As I already said, the free mocking frameworks can mock only interfaces and virtual methods. if you want to mock other things, you need the &lt;a href="http://site.typemock.com/typemock-isolator-product/"&gt;Typemock Isolator&lt;/a&gt; tool for that, which comes with license costs (Although these ‘costs’ are ridiculously low compared to the value that such a tool can bring to a software project, spending money often is a considerable gateway hurdle in real life...).  The Moles framework also is not totally free, but comes with the same license conditions as the (closely related) &lt;a href="http://research.microsoft.com/en-us/projects/pex/"&gt;Pex&lt;/a&gt; framework: It is free for academic/non-commercial use only, to use it in a ‘real’ software project requires an MSDN Subscription (from VS2010pro on).&lt;/p&gt;
    &lt;h1&gt;The demo solution&lt;/h1&gt;
    &lt;p&gt;The sample solution (VS 2008) can be downloaded from &lt;a href="https://www.sugarsync.com/pf/D6769550_9944566_606587"&gt;here&lt;/a&gt;. It contains the &lt;font face="Courier New"&gt;Gallio.Moles.dll&lt;/font&gt; which provides the here described &lt;font face="Courier New"&gt;Moled&lt;/font&gt; attribute, the above mentioned R#-template &lt;font face="Courier New"&gt;(moled_cmd.xml&lt;/font&gt;) and a test fixture containing the above described use case scenarios. To run it, you need the Gallio framework (&lt;a href="http://gallio.org/Downloads.aspx"&gt;download&lt;/a&gt;) and Microsoft Moles (&lt;a href="http://research.microsoft.com/en-us/projects/pex/downloads.aspx"&gt;download&lt;/a&gt;) being installed in the default locations.&lt;/p&gt;
    &lt;p&gt;Happy testing…&lt;/p&gt;
    &lt;p&gt; &lt;/p&gt;
    &lt;table cellspacing="2" cellpadding="6" border="0" width="580" style="background-image: url(&amp;quot;http://gwb.blob.core.windows.net/thomasweller/social/pictures/socialb-580x100.gif&amp;quot;); background-repeat: no-repeat; background-position: -5px 50%;"&gt;
        &lt;tbody&gt;
            &lt;tr style="padding-top: 4px;"&gt;
                &lt;td align="left" width="85" valign="bottom"&gt;
                &lt;div id="kickit"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url="&gt;&lt;img border="0" width="88" height="22" style="position: relative; display: inline; top: 4px; cursor: pointer; padding-top: 6px;" id="kick" title="Kick it!" alt="kickit" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
                &lt;/td&gt;
                &lt;td align="left" width="85" valign="bottom"&gt;
                &lt;div id="shoutit"&gt;&lt;a href="http://dotnetshoutout.com/Submit?url="&gt;&lt;img border="0" style="position: relative; display: inline; top: 4px; cursor: pointer; padding-top: 6px;" id="shout" title="Shout it!" alt="shoutit" src="http://dotnetshoutout.com/image.axd?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
                &lt;/td&gt;
                &lt;td align="left" width="330" valign="middle"&gt;
                &lt;div id="zoneit"&gt;&lt;iframe width="150" scrolling="no" height="20" frameborder="0" style="position: relative; top: 4px;" id="dzoneframe" title="Zone it!" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&amp;amp;url=&amp;amp;title="&gt;&lt;/iframe&gt;&lt;/div&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td valign="middle" colspan="3"&gt;&lt;img border="0" width="32" height="32" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="delicious" title="Bookmark this on Delicious." onclick="setBookmark('delicious');" alt="delicious" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/delicious-32x32.png" /&gt; &lt;a id="fbshare" href="http://www.facebook.com/sharer.php"&gt;&lt;img border="0" width="33" height="33" style="position: relative; border-width: 0px; display: inline; left: 2px;" id="facebook" title="Share this on Facebook." alt="facebook" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/facebook-48x48.png" /&gt;&lt;/a&gt; &lt;img border="0" width="34" height="34" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="digg" title="Digg this." onclick="setBookmark('digg');" alt="digg" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/digg-48x48.png" /&gt; &lt;img border="0" width="33" height="33" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="reddit" title="Reddit this." onclick="setBookmark('reddit');" alt="reddit" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/reddit-48x48.png" /&gt; &lt;img border="0" width="34" height="34" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="linkedin" title="Share this on LinkedIn." onclick="setBookmark('linkedin');" alt="linkedin" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/linkedin-48x48.png" /&gt; &lt;img border="0" width="33" height="33" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="stumbleupon" title="Stumble!" onclick="setBookmark('stumbleupon');" alt="stumbleupon" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/stumbleupon-48x48.png" /&gt; &lt;img border="0" width="32" height="32" style="position: relative; border-width: 0px; display: inline; cursor: pointer; padding-top: 1px; left: 2px;" id="technorati" title="Add this to Technorati." onclick="setBookmark('technorati')" alt="technorati" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/technorati-48x48.png" /&gt; &lt;img border="0" width="32" height="32" style="position: relative; border-width: 0px; margin: 1px 0px 0px 1px; display: inline; cursor: pointer; left: 2px;" id="mrwong" title="Bookmark this on Mister Wong." onclick="setBookmark('mrwong');" alt="mrwong" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/mrwong-32x32.png" /&gt; &lt;img border="0" width="33" height="33" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="yahoobkm" title="Bookmark this on Yahoo." onclick="setBookmark('yahoobkm')" alt="yahoo" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/yahoo-48x48.png" /&gt; &lt;img border="0" width="33" height="33" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="googlebkm" title="Bookmark this on Google." onclick="setBookmark('googlebkm');" alt="google-48x48" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/google-48x48.png" /&gt; &lt;img border="0" width="33" height="33" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="twitter" title="Tweet this (with bit.ly URL)." onclick="BitlyClient.shorten(document.location, 'BitlyCB.shortenResponse');" alt="twitter" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/twitter-48x48.png" /&gt; &lt;img border="0" width="31" height="31" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="mail" title="Send a link via E-Mail." onclick="mailpage();" alt="email" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/email-32x32.png" /&gt; &lt;img border="0" width="32" height="32" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="bookmark" title="Bookmark this page in your browser." onclick="bookmarkInBrowser();" alt="favorites" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/favorites-star-128x128.png" /&gt;&lt;/td&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/139555.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2010/04/28/mocking-the-unmockable-using-microsoft-moles-with-gallio.aspx</guid>
            <pubDate>Wed, 28 Apr 2010 11:36:39 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/139555.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2010/04/28/mocking-the-unmockable-using-microsoft-moles-with-gallio.aspx#feedback</comments>
            <slash:comments>11</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/139555.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A delicious toolbox</title>
            <category>Business</category>
            <category>Open Source</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2010/02/27/a-delicious-toolbox.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2010/02/27/a-delicious-toolbox.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2010/02/27/a-delicious-toolbox.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;One of my major points of interest as a software developer is in the various tools that are available to make a developer’s life easier (or at least more interesting…). This is also a very important aspect for me in professional terms, because one part of my job lies in recommending suitable tools to my customers, implementing them and make them part of a developer team’s workflow. Thus, a well organized link collection is an important part of my assets and has a considerable business value for me - I already mentioned that &lt;a href="http://geekswithblogs.net/thomasweller/archive/2009/10/07/my-technical-library-is-always-with-me.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The overwhelming majority of these links point to some sort of freely available stuff - mostly to OSS projects, related extensions, documentation and the like. I greatly benefit from them in business and professional terms, so it’s only fair to share it back to the community. Maybe it  will be useful to other people as well...&lt;/p&gt;
&lt;p&gt;Therefore, I decided to make my bookmark collection available via &lt;a href="http://delicious.com/"&gt;Delicious&lt;/a&gt;. It is intended to be a central repository for any kind of software development tools, libraries and frameworks that are helpful for C# development; a commented and organized repository which can grow and develop over time, and is easily available from everywhere, both for me and for everyone else.&lt;/p&gt;
&lt;h1&gt;What’s inside ?&lt;/h1&gt;
&lt;p&gt;The toolbox features mainly OSS projects that deal with productivity and code quality issues in the area of C# development, together with some useful links surrounding these tools (like for example relating documentation and relevant blog posts), but occasionally also commercial tools, if I feel that this makes sense. I’ll be not too strict with that: Basically, everything that revolves around my development practice (be it commercial or non-commercial) may appear here. My only not-negotiable requirement for a tool to be included in my toolbox is that it must have the capability to be seamlessly integrated with the usual software development workflow (using Visual Studio and  a Continuous Integration server like e.g. CCNet).&lt;/p&gt;
&lt;p&gt;As for the start, the toolbox covers these tools:&lt;/p&gt;
&lt;p&gt;&lt;u&gt;Subversion      &lt;br /&gt;
&lt;/u&gt;&lt;a href="http://delicious.com/thomasweller/toolbox+subversion"&gt;http://delicious.com/thomasweller/toolbox+subversion&lt;/a&gt;     &lt;br /&gt;
&lt;a href="http://delicious.com/thomasweller/toolbox+SVN"&gt;http://delicious.com/thomasweller/toolbox+SVN&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;Mercurial  &lt;br /&gt;
&lt;/u&gt;&lt;a href="http://delicious.com/thomasweller/toolbox+mercurial"&gt;http://delicious.com/thomasweller/toolbox+mercurial&lt;/a&gt;     &lt;br /&gt;
&lt;a href="http://delicious.com/thomasweller/toolbox+Hg"&gt;http://delicious.com/thomasweller/toolbox+Hg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;Git  &lt;br /&gt;
&lt;/u&gt;&lt;a href="http://delicious.com/thomasweller/toolbox+Git"&gt;http://delicious.com/thomasweller/toolbox+Git&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;CruiseControl.NET      &lt;br /&gt;
&lt;/u&gt;&lt;a href="http://delicious.com/thomasweller/toolbox+cruisecontrol.net"&gt;http://delicious.com/thomasweller/toolbox+cruisecontrol.net&lt;/a&gt;     &lt;br /&gt;
&lt;a href="http://delicious.com/thomasweller/toolbox+ccnet"&gt;http://delicious.com/thomasweller/toolbox+ccnet&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;MSBuild      &lt;br /&gt;
&lt;/u&gt;&lt;a href="http://delicious.com/thomasweller/toolbox+msbuild"&gt;http://delicious.com/thomasweller/toolbox+msbuild&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;LINQPad      &lt;br /&gt;
&lt;/u&gt;&lt;a href="http://delicious.com/thomasweller/toolbox+linqpad"&gt;http://delicious.com/thomasweller/toolbox+linqpad&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This selection is by no means any kind of judgment, rather it roughly mirrors the things with which I’m dealing at the moment. The list will constantly grow in the future…&lt;/p&gt;
&lt;h1&gt;How is it organized ?&lt;/h1&gt;
&lt;p&gt;As you might probably know, bookmarks on Delicious are organized by tags rather than in a hierarchical directory structure. Here is a list of some tags/tag categories that I will regularly use to organize the collection:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;em&gt;&lt;u&gt;toolbox&lt;/u&gt;&lt;/em&gt; - This is the ‘root tag’ (I know, it doesn’t make much sense to use hierarchical notions like that…). So the ‘base address’ of the bookmark collection is &lt;strong&gt;&lt;em&gt;&lt;a href="http://delicious.com/thomasweller/toolbox"&gt;http://delicious.com/thomasweller/toolbox&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;u&gt;&amp;lt;toolname&amp;gt;&lt;/u&gt; - The name of the tool that this bookmark is about (full name and eventually common abbreviations). Example: &lt;em&gt;subversion&lt;/em&gt;, &lt;em&gt;SVN&lt;/em&gt;…&lt;/li&gt;
    &lt;li&gt;&lt;u&gt;&amp;lt;keywords/categories&amp;gt;&lt;/u&gt; - This is pretty free-style and serves to further organize and index the links. Examples:&lt;em&gt; version-control&lt;/em&gt;, &lt;em&gt;VCS&lt;/em&gt;, &lt;em&gt;coding-guidelines&lt;/em&gt;, &lt;em&gt;static-analysis…&lt;/em&gt; &lt;/li&gt;
    &lt;li&gt;&lt;u&gt;&amp;lt;relates-to&amp;gt;&lt;/u&gt; - The tool(s) to which this bookmark relates (e.g. as a plug-in, add-in, or piece of documentation).&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;&lt;u&gt;add-on&lt;/u&gt;&lt;/em&gt; - This piece of software is an extension – usually  a plug-in or add-in, or a collection of them - for the software that appears in the other tags of this bookmark.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;&lt;u&gt;documentation&lt;/u&gt;&lt;/em&gt; - This bookmark links to some sort of documentation relating to the software that appears in the other tags.&lt;/li&gt;
    &lt;li&gt;&lt;u&gt;&amp;lt;documentation-kind&amp;gt;&lt;/u&gt; - Applies to documentation links only. Describes what sort of documentation this link refers to.  Examples: &lt;em&gt;e-book, blog-post, wiki…&lt;/em&gt;&lt;/li&gt;
    &lt;li&gt;&lt;u&gt;&amp;lt;license-kind&amp;gt;&lt;/u&gt; – Applies only to software. The kind of license of the software. One of &lt;em&gt;opensource&lt;/em&gt;, &lt;em&gt;free&lt;/em&gt;, &lt;em&gt;commercial&lt;/em&gt;. If there’s a dual licensing model (e.g. &lt;a href="http://www.db4o.com/"&gt;db4o&lt;/a&gt; or &lt;a href="http://dev.mysql.com/"&gt;MySQL&lt;/a&gt;),  then the free one is used.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;A blog post which explains or demonstrates some aspect of &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl.NET&lt;/a&gt; may have the following tags:       &lt;br /&gt;
    &lt;em&gt;toolbox cruisecontrol.net CCNet documentation blog-post&lt;/em&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://ankhsvn.open.collab.net/"&gt;AnkhSVN&lt;/a&gt;, an open source Visual Studio add-in for &lt;a href="http://subversion.apache.org/"&gt;Subversion&lt;/a&gt; will be tagged like this:       &lt;br /&gt;
    &lt;em&gt;toolbox ankhsvn subversion SVN visualstudio addin opensource&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;font color="#ffffff"&gt;Navigation using tags on Delicious is pretty simple: You just add the desired tags to the base URL using the '+’ sign – i.e.: &lt;strong&gt;&lt;em&gt;http://delicious.com/thomasweller/toolbox+&amp;lt;toolname&amp;gt;[+&amp;lt;othertags&lt;/em&gt;&amp;gt;]&lt;/strong&gt;.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;If you are interested in all sort of documentation that is somehow related to the &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; SCM, then you would use this URL: &lt;a href="http://delicious.com/thomasweller/toolbox+Git+documentation"&gt;http://delicious.com/thomasweller/toolbox+Git+documentation&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;OpenSource, free, or commercial ?&lt;/h1&gt;
&lt;p&gt;When I thought about the organization of the bookmarks collection, one question was whether to have or not to have tags that describe the underlying business model of a tool. In the end, I decided to include this information, albeit in a very coarse-grained form. Here’s why:&lt;/p&gt;
&lt;p&gt;My experience is that from a commercial project’s business perspective, it mostly doesn’t make much sense in the end to distinguish between commercial and non-commercial tools – if you think about costs, you have to think in terms of &lt;a href="http://en.wikipedia.org/wiki/Total_cost_of_ownership"&gt;Total cost of ownership&lt;/a&gt; rather than in terms of license costs. But on the other hand, I made the experience that the willingness to try out something new is usually &lt;em&gt;much&lt;/em&gt; bigger if the tool comes with no initial license costs.&lt;/p&gt;
&lt;p&gt;To me personally, it doesn’t really matter whether something is commercial or not, as long as I see value in it – it basically is a cost-benefit calculation. Sure, I’d always prefer the OpenSource solution, if there’s something to choose, simply because OSS software follows a ‘business model’ that I believe to be highly superior to others, also it is much more flexible and generally has a higher quality standard than a commercial package (at least there always is the potential for that, because OSS projects benefit from the renowned &lt;a href="http://en.wikipedia.org/wiki/Wisdom_of_the_crowd"&gt;Wisdom of the crowd&lt;/a&gt; - only very large companies like e.g. Microsoft can compete with that). Of course, some software products are too heavy for being written and reliably maintained by the community (like e.g. Visual Studio). They need many resources - financial, organizational, and in terms of manpower. And they are definitely worth their price.&lt;/p&gt;
&lt;h4&gt;Last notes&lt;/h4&gt;
&lt;ul&gt;
    &lt;li&gt;The blog now has a tag cloud with the delicious tags on the right (‘Delicious Toolbox’ in the ‘News’ section).&lt;/li&gt;
    &lt;li&gt;Feel free to leave a comment if you think that something should be included into the collection… &lt;input id="summary" style="visibility: hidden;" value="As a software developer, I'm especially interested in the various tools that are available to make a developer’s life easier. The knowledge about these tools also forms a substantial part of my professional assets. Most of the links that I bookmarked over the years point to some freely available stuff (e.g. OSS projects), and therefore I decided to make the collection available via Delicious. Maybe it  will be useful to other people as well..." /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table width="580" cellspacing="2" cellpadding="6" border="0" style="background-image: url(&amp;quot;http://gwb.blob.core.windows.net/thomasweller/social/pictures/socialb-580x100.gif&amp;quot;); background-repeat: no-repeat; background-position: -5px 50%;"&gt;
    &lt;tbody&gt;
        &lt;tr style="padding-top: 4px;"&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="kickit"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url="&gt;                             &lt;img width="88" height="22" border="0" style="padding-top: 6px; position: relative; top: 4px; display: inline; cursor: pointer;" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=" alt="kickit" title="Kick it!" id="kick" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="shoutit"&gt;&lt;a href="http://dotnetshoutout.com/Submit?url="&gt;                             &lt;img border="0" style="padding-top: 6px; position: relative; top: 4px; display: inline; cursor: pointer;" src="http://dotnetshoutout.com/image.axd?url=" alt="shoutit" title="Shout it!" id="shout" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="330" valign="middle" align="left"&gt;
            &lt;div id="zoneit"&gt;&lt;iframe width="150" height="20" frameborder="0" scrolling="no" id="dzoneframe" title="Zone it!" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&amp;amp;url=&amp;amp;title=" style="position: relative; top: 4px;"&gt;&lt;/iframe&gt;&lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="middle" colspan="3"&gt;&lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/delicious-32x32.png" alt="delicious" onclick="setBookmark('delicious');" title="Bookmark this on Delicious." id="delicious" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;a id="fbshare" href="http://www.facebook.com/sharer.php"&gt;&lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/facebook-48x48.png" alt="facebook" title="Share this on Facebook." id="facebook" style="position: relative; border-width: 0px; display: inline; left: 2px;" /&gt;&lt;/a&gt; &lt;img width="34" height="34" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/digg-48x48.png" alt="digg" onclick="setBookmark('digg');" title="Digg this." id="digg" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/reddit-48x48.png" alt="reddit" onclick="setBookmark('reddit');" title="Reddit this." id="reddit" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="34" height="34" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/linkedin-48x48.png" alt="linkedin" onclick="setBookmark('linkedin');" title="Share this on LinkedIn." id="linkedin" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/stumbleupon-48x48.png" alt="stumbleupon" onclick="setBookmark('stumbleupon');" title="Stumble!" id="stumbleupon" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/technorati-48x48.png" alt="technorati" onclick="setBookmark('technorati')" title="Add this to Technorati." id="technorati" style="position: relative; border-width: 0px; display: inline; cursor: pointer; padding-top: 1px; left: 2px;" /&gt; &lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/mrwong-32x32.png" alt="mrwong" onclick="setBookmark('mrwong');" title="Bookmark this on Mister Wong." id="mrwong" style="position: relative; border-width: 0px; margin: 1px 0px 0px 1px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/yahoo-48x48.png" alt="yahoo" onclick="setBookmark('yahoobkm')" title="Bookmark this on Yahoo." id="yahoobkm" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/google-48x48.png" alt="google-48x48" onclick="setBookmark('googlebkm');" title="Bookmark this on Google." id="googlebkm" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="33" height="33" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/twitter-48x48.png" alt="twitter" onclick="BitlyClient.shorten(document.location, 'BitlyCB.shortenResponse');" title="Tweet this (with bit.ly URL)." style="border-width: 0px; display: inline; cursor: pointer; left: 2px; position: relative;" id="twitter" /&gt; &lt;img width="31" height="31" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/email-32x32.png" alt="email" onclick="mailpage();" title="Send a link via E-Mail." id="mail" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt; &lt;img width="32" height="32" border="0" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/favorites-star-128x128.png" alt="favorites" onclick="bookmarkInBrowser();" title="Bookmark this page in your browser." id="bookmark" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt; &lt;/p&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/138214.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2010/02/27/a-delicious-toolbox.aspx</guid>
            <pubDate>Sat, 27 Feb 2010 13:50:58 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/138214.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2010/02/27/a-delicious-toolbox.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/138214.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Making Selenium 1.0.1 work with Firefox 3.6</title>
            <category>Automation</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2010/02/14/making-selenium-1.0.1-work-with-firefox-3.6.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2010/02/14/making-selenium-1.0.1-work-with-firefox-3.6.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2010/02/14/making-selenium-1.0.1-work-with-firefox-3.6.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;These days, I’m doing a bit of end-to-end acceptance web testing using the &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; framework. Selenium has a nice and handy add-on for the &lt;a href="http://www.mozilla.com/en-US/"&gt;Firefox&lt;/a&gt; browser – the &lt;a href="http://seleniumhq.org/projects/ide/"&gt;Selenium IDE&lt;/a&gt;. It automatically records your actions and produces the required C# code for you, as you click around in the browser window.&lt;/p&gt;
&lt;p&gt;But when I started the Selenium server and tried to run my first test (copied from the Selenium docs), it didn’t work (Sigh. It &lt;strong&gt;never&lt;/strong&gt; works on the first try…) and I got a timeout and an exception. This is what my &lt;a href="http://gallio.org"&gt;Gallio&lt;/a&gt; test report showed:&lt;/p&gt;
&lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; background: none repeat scroll 0% 0% rgb(221, 221, 221); overflow: scroll;"&gt;&lt;img width="1211" height="330" border="0" src="http://gwb.blob.core.windows.net/thomasweller/WindowsLiveWriter/MakingSelenium1.0.1playwithFirefox3.6_7000/SeleniumException_3.gif" alt="SeleniumException" title="SeleniumException" style="border-width: 0px; display: inline;" /&gt;&lt;/div&gt;
&lt;p&gt;Huh? A file could not be deleted (obviously a temporary file that is internally used by the browser)? The Selenium docs were not of much help here.&lt;/p&gt;
&lt;p&gt;When I thought it over for a minute, I started to suspect what the real, underlying problem could be: I’m using the new 3.6 version of Firefox, which is about half a year more recent than the current Selenium release. So it might be again an incarnation of our good old friend named ‘version mismatch’… Searching Google for ‘&lt;em&gt;selenium firefox 3.6&lt;/em&gt;’ quickly revealed that I was right: the problem simply is that the Selenium server only accepts Firefox versions up to 3.5. This can easily be corrected. Here’s how:&lt;/p&gt;
&lt;p&gt;  ---  Remark: The following solution includes the usage of the free &lt;a href="http://www.7-zip.org/"&gt;7-Zip&lt;/a&gt; file archiver.  --&lt;/p&gt;
&lt;p&gt;1. In Windows Explorer, go to the directory where your Selenium server is located (i.e. where the ‘&lt;font face="Courier New" size="2"&gt;selenium-server.jar&lt;/font&gt;’ file lives). After you made a backup of the original file, open it directly with 7-Zip (a *.jar file is actually a compressed archive).&lt;/p&gt;
&lt;p&gt;2. We need to patch five instances of a file called ‘&lt;font face="Courier New" size="2"&gt;install.rdf&lt;/font&gt;’ (they actually are small xml files). These files can be found at the following locations in the ‘&lt;font face="Courier New" size="2"&gt;selenium-server.jar&lt;/font&gt;’ archive:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;font face="Courier New" size="2"&gt;customProfileDirCUSTFF/extensions/&lt;/font&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;        {538F0036-F358-4f84-A764-89FB437166B4} &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;        readystate@openqa.org &lt;/font&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;font face="Courier New" size="2"&gt;customProfileDirCUSTFFCHROME/extensions/&lt;/font&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;        {503A0CD4-EDC8-489b-853B-19E0BAA8F0A4} &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;        {538F0036-F358-4f84-A764-89FB437166B4} &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;        readystate@openqa.org&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;3. Open each of these files (directly from within 7-Zip) with Notepad or any other text/xml editor. Replace the following text…&lt;/p&gt;
&lt;p style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: small;"&gt;&amp;lt;em:maxVersion&amp;gt;3.5.*&amp;lt;/em:maxVersion&amp;gt;&lt;/p&gt;
&lt;p&gt;… with this (you might have guessed it already):&lt;/p&gt;
&lt;div style="border: thin solid rgb(128, 128, 128); padding: 8px 2px 8px 6px; font-family: 'Courier New',courier,monospace; white-space: nowrap; background: none repeat scroll 0% 0% rgb(221, 221, 221); color: black; font-size: small;"&gt;&amp;lt;em:maxVersion&amp;gt;3.6.*&amp;lt;/em:maxVersion&amp;gt;&lt;/div&gt;
&lt;p&gt;4. Notepad (or your favorite text/xml editing tool) will ask you to confirm your changes, and so will 7-zip immediately after the file change. Confirm all, close the archive after you’re done, and start the selenium server as usual.&lt;/p&gt;
&lt;p&gt;Happy testing…&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table width="580" cellspacing="2" cellpadding="6" border="0" style="background-image: url(&amp;quot;http://gwb.blob.core.windows.net/thomasweller/social/pictures/socialb-580x100.gif&amp;quot;); background-repeat: no-repeat; background-position: -5px 50%;"&gt;
    &lt;tbody&gt;
        &lt;tr style="padding-top: 4px;"&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="kickit"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url="&gt;&lt;img width="88" height="22" border="0" style="position: relative; display: inline; top: 4px; cursor: pointer; padding-top: 6px;" id="kick" title="Kick it!" alt="kickit" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="85" valign="bottom" align="left"&gt;
            &lt;div id="shoutit"&gt;&lt;a href="http://dotnetshoutout.com/Submit?url="&gt;&lt;img border="0" src="http://dotnetshoutout.com/image.axd?url=" alt="shoutit" title="Shout it!" id="shout" style="position: relative; display: inline; top: 4px; cursor: pointer; padding-top: 6px;" /&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/td&gt;
            &lt;td width="330" valign="middle" align="left"&gt;
            &lt;div id="zoneit"&gt;&lt;iframe width="150" height="20" frameborder="0" scrolling="no" style="position: relative; top: 4px;" id="dzoneframe" title="Zone it!" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&amp;amp;url=&amp;amp;title="&gt;&lt;/iframe&gt;&lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td valign="middle" colspan="3"&gt;&lt;img width="32" height="32" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="delicious" title="Bookmark this on Delicious." onclick="setBookmark('delicious');" alt="delicious" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/delicious-32x32.png" /&gt; &lt;a id="fbshare" href="http://www.facebook.com/sharer.php"&gt;&lt;img width="33" height="33" border="0" style="position: relative; border-width: 0px; display: inline; left: 2px;" id="facebook" title="Share this on Facebook." alt="facebook" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/facebook-48x48.png" /&gt;&lt;/a&gt; &lt;img width="34" height="34" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="digg" title="Digg this." onclick="setBookmark('digg');" alt="digg" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/digg-48x48.png" /&gt; &lt;img width="33" height="33" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="reddit" title="Reddit this." onclick="setBookmark('reddit');" alt="reddit" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/reddit-48x48.png" /&gt; &lt;img width="34" height="34" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="linkedin" title="Share this on LinkedIn." onclick="setBookmark('linkedin');" alt="linkedin" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/linkedin-48x48.png" /&gt; &lt;img width="33" height="33" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="stumbleupon" title="Stumble!" onclick="setBookmark('stumbleupon');" alt="stumbleupon" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/stumbleupon-48x48.png" /&gt; &lt;img width="32" height="32" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; padding-top: 1px; left: 2px;" id="technorati" title="Add this to Technorati." onclick="setBookmark('technorati')" alt="technorati" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/technorati-48x48.png" /&gt; &lt;img width="32" height="32" border="0" style="position: relative; border-width: 0px; margin: 1px 0px 0px 1px; display: inline; cursor: pointer; left: 2px;" id="mrwong" title="Bookmark this on Mister Wong." onclick="setBookmark('mrwong');" alt="mrwong" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/mrwong-32x32.png" /&gt; &lt;img width="33" height="33" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="yahoobkm" title="Bookmark this on Yahoo." onclick="setBookmark('yahoobkm')" alt="yahoo" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/yahoo-48x48.png" /&gt; &lt;img width="33" height="33" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="googlebkm" title="Bookmark this on Google." onclick="setBookmark('googlebkm');" alt="google-48x48" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/google-48x48.png" /&gt; &lt;img width="33" height="33" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="twitter" title="Tweet this (with bit.ly URL)." onclick="BitlyClient.shorten(document.location, 'BitlyCB.shortenResponse');" alt="twitter" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/twitter-48x48.png" /&gt; &lt;img width="31" height="31" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="mail" title="Send a link via E-Mail." onclick="mailpage();" alt="email" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/email-32x32.png" /&gt; &lt;img width="32" height="32" border="0" style="position: relative; border-width: 0px; display: inline; cursor: pointer; left: 2px;" id="bookmark" title="Bookmark this page in your browser." onclick="bookmarkInBrowser();" alt="favorites" src="http://gwb.blob.core.windows.net/thomasweller/social/pictures/favorites-star-128x128.png" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/137960.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2010/02/14/making-selenium-1.0.1-work-with-firefox-3.6.aspx</guid>
            <pubDate>Sun, 14 Feb 2010 09:00:15 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/137960.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2010/02/14/making-selenium-1.0.1-work-with-firefox-3.6.aspx#feedback</comments>
            <slash:comments>10</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/137960.aspx</wfw:commentRss>
        </item>
        <item>
            <title>miniSCRUM &amp;ndash; things can be soo easy and simple</title>
            <category>Project Management</category>
            <link>http://geekswithblogs.net/thomasweller/archive/2010/02/02/miniscrum-ndash-things-can-be-soo-easy-and-simple.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://geekswithblogs.net/thomasweller/archive/2010/02/02/miniscrum-ndash-things-can-be-soo-easy-and-simple.aspx'&gt;http://geekswithblogs.net/thomasweller/archive/2010/02/02/miniscrum-ndash-things-can-be-soo-easy-and-simple.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Yesterday, I occasionally stumbled upon &lt;a href="http://miniscrum.com/"&gt;miniSCRUM&lt;/a&gt;, a free online &lt;a href="http://en.wikipedia.org/wiki/Scrum_%28development%29"&gt;Scrum&lt;/a&gt; tool. It’s for sure not the first Scrum project management tool that I examined – but the ones that I’ve seen and tried so far were too complicated and/or required too much knowledge about Scrum or the tool itself or both. In the end, these tools always introduced more problems than they solved, they got in my development way and made me less productive, not more.&lt;/p&gt;
&lt;p&gt;Not so miniSCRUM. It’s dead simple and therefore totally intuitive in its usage. In fact, it takes longer to read the documentation than just to begin using it. It’s a perfect example for the &lt;a href="http://en.wikipedia.org/wiki/Keep_It_Simple_Stupid"&gt;KISS principle&lt;/a&gt;: Only the bare minimum of Scrum features are available, and a five-minute introduction to the basic ideas behind Scrum is enough to understand them.&lt;/p&gt;
&lt;p&gt;If you want to give Scrum a try, or play around with the idea of iterative project planning/estimating, or do some Solo Scrum for your own personal stuff, or if you don’t care too much about the theoretical background of Scrum (at least not in the beginning), then miniSCRUM is for you. It’s a perfect starting point to see how it feels and how it can work for you. All you need is an &lt;a href="http://en.wikipedia.org/wiki/OpenID"&gt;OpenID&lt;/a&gt; to sign in.&lt;/p&gt;
&lt;p&gt;I immediately and hopelessly fell in love with miniSCRUM. I will use it for my own personal projects and I will also recommend it to anyone who wants to give Scrum a first try…&lt;/p&gt; &lt;img src="http://geekswithblogs.net/thomasweller/aggbug/137750.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Thomas Weller</dc:creator>
            <guid>http://geekswithblogs.net/thomasweller/archive/2010/02/02/miniscrum-ndash-things-can-be-soo-easy-and-simple.aspx</guid>
            <pubDate>Tue, 02 Feb 2010 05:21:19 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/thomasweller/comments/137750.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/thomasweller/archive/2010/02/02/miniscrum-ndash-things-can-be-soo-easy-and-simple.aspx#feedback</comments>
            <slash:comments>13</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/thomasweller/comments/commentRss/137750.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>