<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Derik Whittaker : Linq, TDD</title><link>http://devlicio.us/blogs/derik_whittaker/archive/tags/Linq/TDD/default.aspx</link><description>Tags: Linq, TDD</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Using Linq's DataContext to (re)create your database for testing</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2008/05/21/using-linq-s-datacontext-to-re-create-your-database-for-testing.aspx</link><pubDate>Wed, 21 May 2008 16:24:12 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:40689</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=40689</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=40689</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2008/05/21/using-linq-s-datacontext-to-re-create-your-database-for-testing.aspx#comments</comments><description>&lt;p&gt;If you happen to be using Linq2Sql and are also someone who tests, I have something for you.&amp;#160; You can use Linq&amp;#39;s DataContext to create your database and then populate it with test data prior to each test run.&amp;#160; Note that you can do this same thing when using other OR/M tools such as NHIbernate, so this is nothing new or revolutionary.&lt;/p&gt;  &lt;p&gt;Before I get into the &amp;#39;How To&amp;#39; on doing this, I would like to go over the &amp;#39;Why&amp;#39; I should do this.&lt;/p&gt;  &lt;p&gt;When building out your test suit on any data driven application you are going to need to test data access at some point.&amp;#160; There are really 3 solutions to this problem.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Simply query for known, existing data      &lt;br /&gt;Although this works, this leads to very weak and brittle tests for obvious reasons.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Create/use/delete the data for each of your tests      &lt;br /&gt;This is a better choice, but leads to very heavy tests and can also lead to bad or orphaned data.&amp;#160; Which can be a major pain point if this is done in your development environment.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Rebuild the db and test data for each test run.      &lt;br /&gt;To me, this is the best choice as you get a clean slate and any orphaned data will be destroyed after each run.&amp;#160; No harm, no foul &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Ok, on to the How to of this post.&lt;/p&gt;  &lt;p&gt;The first thing you need to do is setup your tests to have your test fixture have FixtureSetup/FixtureTearDown methods to perform building/destroying of the database.&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;private TestsInit _testsInit;

[TestFixtureSetUp]
public void FixtureSetup()
{
    _testsInit = ObjectFactory.GetInstance&amp;lt; TestsInit &amp;gt;();
    _testsInit.InitDatabase();
}

[TestFixtureTearDown]
public void FixtureTeardown()
{
    _testsInit.DestroyDatabase();
}&lt;/pre&gt;

&lt;p&gt;Once you have your Setup/TearDown implemented you need to create the logic to build the database and insert test data.&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;public void InitDatabase()
{
    var dbContext = new DBContextDataContext( ConfigurationReader.ConnectionString_ForTests );
 
    CreateDatabase( dbContext );
    CreateTypeData( dbContext );
    CreateTestEpisode( dbContext );
}

public void DestroyDatabase()
{
    var dbContext = new DBContextDataContext( ConfigurationReader.ConnectionString_ForTests );

    DeleteDatabase( dbContext );
}

private void CreateDatabase( DataContext dbContext )
{
    DeleteDatabase( dbContext );

    dbContext.CreateDatabase();            
}

public void CreateTypeData( DBContextDataContext dbContext )
{
    dbContext.ExecuteCommand( &amp;quot;INSERT INTO [LevelType]( Name ) VALUES ( &amp;#39;Type 1&amp;#39; )&amp;quot; );
    .....
    dbContext.ExecuteCommand( &amp;quot;INSERT INTO [TagTypes]( Name ) VALUES ( &amp;#39;Type 4&amp;#39; )&amp;quot; );
}

private void CreateTestEpisode( DBContextDataContext dbContext )
{
    Episode episode = new Episode {LevelTypeID = 1, Name = &amp;quot;Test 1&amp;quot;, Description = &amp;quot;Desc 1&amp;quot;, EpisodeNumber = 1, EpisodeDate = DateTime.Now};
    ....

    episode.EpisodeDownloadInformations = new EntitySet&amp;lt; EpisodeDownloadInformation &amp;gt;
                                              {
                                                  new EpisodeDownloadInformation{ FileName = &amp;quot;Foo.wmv&amp;quot;, Size = 9.25m, Time = &amp;quot;10:00&amp;quot; }
                                              };

    dbContext.Episodes.InsertOnSubmit( episode );
    dbContext.SubmitChanges();
}


private void DeleteDatabase( DataContext dbContext )
{
    if ( dbContext.DatabaseExists() )
    {
        dbContext.DeleteDatabase();
    }
}&lt;/pre&gt;

&lt;p&gt;One thing to be careful of here is that you are using an alternate connection string, not the one for your dev/stage/production environment or you will NOT be a happy developer.&amp;#160; Also notice that I both using the ExecuteCmmand statement as well as the object model to insert the test data.&amp;#160; This is done simply to show the concept.&amp;#160; You could also simple script up all the inserts and put them into an external file.&amp;#160; The way you do it is up to you.&lt;/p&gt;

&lt;p&gt;So there you go, you now know how you can use the DataContext to build/destroy your db structure for each test run.&lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=40689" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/TDD/default.aspx">TDD</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Linq/default.aspx">Linq</category></item></channel></rss>