tag:blogger.com,1999:blog-37007292214062825082024-03-24T07:10:05.688+00:00Rab Hallett's blogRabhttp://www.blogger.com/profile/03147240392999345216noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-3700729221406282508.post-62078095907056544312010-08-28T14:05:00.018+01:002010-08-31T18:50:48.905+01:00Unit Testing Entity Framework 4.0: A-Z in 3 Easy StepsThis article gives you an ultra-fast run down on how to start Unit Testing in <b>Entity Framework 4.0</b> using <b>C#</b>; applying a suitable <b>Code Generation Item</b> to your <b>Entity Data Model (EDMX)</b> file, and building a <b>Unit Test Project</b> in <b>Visual Studio 2010</b>.<br />
<br />
No external test harness is required, it doesn't rely on having a Repository pattern being implemented and you don't need to buy any new products. Just <b>Visual Studio 2010 Professional Edition, Premium Edition</b> or <b>Ultimate Edition</b> out of the box.<br />
<br />
<table style="border-collapse: collapse; margin-right: 5%;">
<tr><th class="glossary_box";">Terminology</th></tr>
<tr><td class="glossary_box">
The <b>EDMX Code Generation Item</b> used in this article generates two <a href="http://msdn.microsoft.com/library/system.data.objects.objectcontext.aspx"><b>ObjectContext</b></a> classes. When we refer to the <b><i>Vanilla</i> ObjectContext</b>, this is the same strongly typed ObjectContext that is generated from your <b>EDMX</b> by default. The <b><i>Mocking</i> ObjectContext</b> we refer to is another context used only for unit testing, which implements the same strongly typed interface, and is also generated from your <b>EDMX</b> file.<br />
<br />
More details on the architecture of the artifact generator are provided <a href="http://blogofrab.blogspot.com/2010/08/maintenance-free-mocking-for-unit.html">here</a>.</td></tr>
<tr></tr>
</table>
<br/>
<hr/>
<h1 class="post">
Step 1: Set Up the Code Generation Item</h1>
These steps will change your <b>EDMX Code Generation Item</b> to the <a href="http://blogofrab.blogspot.com/2010/08/maintenance-free-mocking-for-unit.html"><b>ADO.NET Mocking Context Generator</b></a>. This is what makes your C# code from your <b>Entity Data Model (EDMX)</b> file.
<ul>
<li>Open your EDMX file, right click the background, and from the context menu select <b>Add Code Generation Item</b>.</li>
<li>Select <b>Online Templates</b>-><b>Database</b>-><b>ADO.NET Mocking Context Generator</b>:</li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOk8G5AMrWWECJJ2emdQizuQu_43hedy0AUNqJsPL8iu2QVLERZ5DF4R-4o2KPSBwCtebGjMo51viCBkWGWPn-t5oy1urgf0JgEBOpAD8Pg-EjX182zdYWpIJ36dOTQz4vbCBiei3QooJN/s1600/add_new_item.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOk8G5AMrWWECJJ2emdQizuQu_43hedy0AUNqJsPL8iu2QVLERZ5DF4R-4o2KPSBwCtebGjMo51viCBkWGWPn-t5oy1urgf0JgEBOpAD8Pg-EjX182zdYWpIJ36dOTQz4vbCBiei3QooJN/s400/add_new_item.png" /></a></div>
<br />
<ul>
<li>Open your EDMX file, right click the background, and from the context menu select <b>Properties</b>.</li>
<li>In the <b>Properties</b> change <b>Code Generation Strategy</b> to <b>None</b>. This will turn off the <i>default</i> Code Generation Item.</li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvmY1_x7Li12lYRR0sCHPKCsZXDdlW555yUDNGKlC3gYjgH2PVHMXCsokBGEGzCldYynp1xEnNcnUYudAytcwh3XEyuwcN0Qhm8YqeuGrfJymD9Kq2ph_-GINU-ZncWJsh_Fakt6xwtf71/s1600/edmx_properties.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvmY1_x7Li12lYRR0sCHPKCsZXDdlW555yUDNGKlC3gYjgH2PVHMXCsokBGEGzCldYynp1xEnNcnUYudAytcwh3XEyuwcN0Qhm8YqeuGrfJymD9Kq2ph_-GINU-ZncWJsh_Fakt6xwtf71/s640/edmx_properties.png" /></a></div>
<br />
<hr/>
<h1 class="post">
Step 2: Ensure "Context Agnostic" Code</h1>
<b>Context Agnostic</b> means that your <b>Business Logic</b> code shouldn't be aware of what context class it is using. We need to ensure that any <b>hard dependencies</b> on your generated <b>Vanilla <a href="http://msdn.microsoft.com/library/system.data.objects.objectcontext.aspx">ObjectContext</a></b> are replaced with references to your new generated <b>ObjectContext Interface</b> instead.<br />
<br />
<h2 class="post">
Identify Context "Gnostic" Code</h2>
We need to find anywhere in your <b>Business Logic Layer</b> that references the vanilla concrete <a href="http://msdn.microsoft.com/library/system.data.objects.objectcontext.aspx"><b>ObjectContext</b></a>:<br />
<br />
<pre style="color: black;"><span style="color: blue;">class</span><span style="color: #2b91af;"> MovieLogic</span>
{
<span style="color: blue;">private</span><span style="color: #2b91af;"> MoviesContext</span> _context; <span style="color: green;">// Hard dependency on vanilla ObjectContext</span><span style="color: blue;">
public</span> MovieLogic()
{
_context = <span style="color: blue;">new</span><span style="color: #2b91af;"> MoviesContext</span>(); <span style="color: green;">// Hard dependency on vanilla ObjectContext</span>
}
}</pre>
<br />
<h2 class="post">
Option 1: Delegate responsibility to the client</h2>
To remove the hard dependency, the simplest option is to ensure all <b>ObjectContext</b> references use the <b>ObjectContext Interface</b> instead, and take on the <b>ObjectContext</b> instance in their constructor:<br />
<pre style="color: black;"><span style="color: blue;">class</span><span style="color: #2b91af;"> MovieLogic</span>
{
<span style="color: blue;">private</span><span style="color: #2b91af;"> IMoviesContext</span> _context; <span style="color: green;">// Interface used instead: context agnostic</span><span style="color: blue;">
public</span> MovieLogic( <span style="color: #2b91af;">IMoviesContext</span> context )
{
_context = context; <span style="color: green;">// Instantiation responsibility is delegated to caller</span>
}
}</pre>
The <b>Business Logic Client</b> can then be re-engineered to instantiate a vanilla <a href="http://msdn.microsoft.com/library/system.data.objects.objectcontext.aspx"><b>ObjectContext</b></a> object for us when the Business Logic object is instantiated:<br />
<pre style="color: #2b91af;">MovieLogic<span style="color: black;"> logic = </span><span style="color: blue;">new</span> MovieLogic<span style="color: black;">( </span><span style="color: blue;">new</span> MoviesContext<span style="color: black;">() );</span></pre>
<table class="glossary_box">
<tr><th class="glossary_box">Note</th></tr>
<tr><td class="glossary_box">
Your application will never instantiate a <b>Mocking Context</b>, as this is only used when testing your business logic in your <b>Unit Test Project</b>.
</td></tr>
</table>
<br />
<br />
<br />
<h2 class="post">
Option 2: Delegate responsibility to a factory</h2>
If your Business Logic objects are instantiated all over the place, then it might be easier to contain the instantiation responsibility within a factory, and call the factory when a context is needed from the Business Logic objects themselves:<br />
<pre style="color: black;"><span style="color: blue;">class</span><span style="color: #2b91af;"> MovieLogic</span>
{
<span style="color: blue;">private</span><span style="color: #2b91af;"> IMoviesContext</span> _context;
<span style="color: blue;">public</span> MovieLogic()
{
_context = <span style="color: #2b91af;">MyContextFactory</span>.CreateContext();
<span style="color: green;">// Instantiation responsibility is delegated to factory</span>
}
}</pre>
<table class="glossary_box">
<tr><th class="glossary_box">Implementing the Factory</th></tr>
<tr><td class="glossary_box">
Whilst no implementation of an example factory is given here, the factory just needs to return a new instance of your <b>Vanilla ObjectContext</b>, unless the "testing" flag is raised, when a <b>Mocking ObjectContext</b> will be instantiated instead.
</td></tr>
</table>
<br />
<br />
<hr/>
<h1 class="post">
Step 3: Create the Unit Tests</h1>
To create the unit tests in <b>Visual Studio</b>, a new test project needs to be created. This project will contain the Unit Test class that runs all the tests, and the code required to set up the mocking context, mock data, and the calls to the business logic.<br />
<ul>
<li>Right click your solution, and select <b>Add -> New Project</b></li>
<li>From the <b>Add New Project Dialog</b> select <b>Visual C# -> Test -> Test Project:</b></li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6lR9ci8h0f-FTGU5gm85SVo_7Fv4KtnGNJflQZr-WyadL7wEiV11ipQAYTOvWbe2onj1KFLq8pkWJUtuopUXII-gH1LxGyy0RiCKmbL_j9Ll5XdUIzWQVJenDmyZk9ymzASytZ39QtqGX/s1600/add_test_project.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6lR9ci8h0f-FTGU5gm85SVo_7Fv4KtnGNJflQZr-WyadL7wEiV11ipQAYTOvWbe2onj1KFLq8pkWJUtuopUXII-gH1LxGyy0RiCKmbL_j9Ll5XdUIzWQVJenDmyZk9ymzASytZ39QtqGX/s320/add_test_project.png" /></a></div>
<br />
<ul>
<li>Add a <b>Reference</b> in your new test project to your <b>Business Logic</b> Project.</li>
<li>Add a <b>Reference</b> to <a href="http://msdn.microsoft.com/en-gb/library/system.data.aspx"><b>System.Data</b></a></li>
<li>Add a <b>Reference</b> to <b>System.Data.Entity</b></li>
</ul>
<br />
<h2 class="post">
Set up the test "database"</h2>
This step creates a fresh mocking context before every test is executed. The mocking context is populated with some sample data that the tests can use. Additionally any test can set up its own data as part of its testing.<br />
<ul>
<li>In your new test project, open your <b>Unit Test</b> code file (eg. "UnitTest1.cs")</li>
<li>Add a member (eg. <code>_context</code>) to your unit test class, of the type of your <b>ObjectContext Interface</b>. The name of the interface will be shown if you expand the <b>*.Context.tt</b> file in the project containing your <b>EDMX</b> file:</li>
<br />
<pre style="color: blue;">private<span style="color: #2b91af;"> IMoviesContext</span><span style="color: black;"> _context;</span></pre>
<li>Add a new function with the <a href="http://msdn.microsoft.com/library/microsoft.visualstudio.testtools.unittesting.testinitializeattribute.aspx"><b>TestInitialize</b></a> attribute. This will cause your function to be executed before every test. Create a mock context and fill it with your mock data. The name of the mocking context class will be shown if you expand the <b>*.Context.tt</b> file in the project containing your <b>EDMX</b> file:</li>
</li>
<br />
<pre style="color: black;">[<span style="color: #2b91af;">TestInitialize</span>]
<span style="color: blue;">public void</span> TestInitialize()
{
_context = <span style="color: blue;">new</span><span style="color: #2b91af;"> MoviesContextMock</span>();
<span style="color: #2b91af;">Actor</span>[] actors = <span style="color: blue;">new</span><span style="color: #2b91af;"> Actor</span>[]
{
<span style="color: blue;">new</span><span style="color: #2b91af;"> Actor</span>() { Id = 1, Name = <span style="color: #a31515;">"Robert De Niro"</span> },
<span style="color: blue;">new</span><span style="color: #2b91af;"> Actor</span>() { Id = 2, Name = <span style="color: #a31515;">"Ray Liotta"</span> },
<span style="color: blue;">new</span><span style="color: #2b91af;"> Actor</span>() { Id = 3, Name = <span style="color: #a31515;">"Joe Pesci"</span> },
<span style="color: blue;">new</span><span style="color: #2b91af;"> Actor</span>() { Id = 4, Name = <span style="color: #a31515;">"Jodie Foster"</span> }
};
<span style="color: #2b91af;">Movie</span>[] movies = <span style="color: blue;">new</span><span style="color: #2b91af;"> Movie</span>[]
{
<span style="color: blue;">new</span><span style="color: #2b91af;"> Movie</span>() { Id = 1, Title = <span style="color: #a31515;">"Goodfellas"</span>, ReleaseYear = 1990, Rating=5 },
<span style="color: blue;">new</span><span style="color: #2b91af;"> Movie</span>() { Id = 2, Title = <span style="color: #a31515;">"Taxi Driver"</span>, ReleaseYear = 1976, Rating=5 },
};
movies[ 0 ].Cast.Add( actors[ 0 ] );
movies[ 0 ].Cast.Add( actors[ 1 ] );
movies[ 0 ].Cast.Add( actors[ 2 ] );
movies[ 1 ].Cast.Add( actors[ 0 ] );
movies[ 1 ].Cast.Add( actors[ 3 ] );
actors.ToList().ForEach( actor => _context.Actors.AddObject( actor ) );
movies.ToList().ForEach( movie => _context.Movies.AddObject( movie ) );
}</pre>
</ul>
<br />
<br />
<h2 class="post">
Implement Test Methods</h2>
Create some functions on your new unit test class, with the attribute <a href="http://msdn.microsoft.com/library/microsoft.visualstudio.testtools.unittesting.testmethodattribute.aspx"><b>TestMethod</b></a>. These will execute the individual unit tests for your business logic.<br />
<br />
Use the <a href="http://msdn.microsoft.com/library/microsoft.visualstudio.testtools.unittesting.assert.aspx"><b>Assert.*</b></a> methods to check the results of calls to your business logic. These calls will be evaluated by the test engine.<br />
<br />
<pre style="color: black;">[<span style="color: #2b91af;">TestMethod</span>]
<span style="color: blue;">public void</span> TestGetMovieByTitle()
{
<span style="color: #2b91af;">MovieLogic</span> logic = <span style="color: blue;">new</span><span style="color: #2b91af;"> MovieLogic</span>( _context );
<span style="color: #2b91af;">Movie</span> movie = logic.GetMovieByTitle( <span style="color: #a31515;">"Goodfellas"</span> );
<span style="color: #2b91af;">Assert</span>.AreEqual( 1, movie.Id );
}
[<span style="color: #2b91af;">TestMethod</span>]
<span style="color: blue;">public void</span> TestGetMovieByTitleBad()
{
<span style="color: #2b91af;">MovieLogic</span> logic = <span style="color: blue;">new</span><span style="color: #2b91af;"> MovieLogic</span>( _context );
<span style="color: #2b91af;">Movie</span> movie = logic.GetMovieByTitle( <span style="color: #a31515;">"Arial the Little Mermaid"</span> );
<span style="color: #2b91af;">Assert</span>.AreEqual( <span style="color: blue;">null</span>, movie );
}
[<span style="color: #2b91af;">TestMethod</span>]
<span style="color: blue;">public void</span> TestGetMovieByReleaseYear()
{
<span style="color: #2b91af;">MovieLogic</span> logic = <span style="color: blue;">new</span><span style="color: #2b91af;"> MovieLogic</span>( _context );
<span style="color: #2b91af;">Movie</span>[] movies = logic.GetMovieByReleaseYear( 1976 );
<span style="color: #2b91af;">Assert</span>.AreEqual( 1, movies.Length );
<span style="color: #2b91af;">Assert</span>.AreEqual( <span style="color: #a31515;">"Taxi Driver"</span>, movies[ 0 ].Title );
}</pre>
</li>
<br />
<br />
<hr/>
<h1 class="post">
Running the Tests</h1>
To run the tests, select <b>Test -> Run -> All Tests In Solution</b>.<br />
The <b>Test Results</b> panel will pop up, and give you the results of your tests:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5B2_RTlFEZUnrlhNmc67VNayxqAGv2l8t-q95fGK6-b3DsD3fN9_PRkexDz8zQZc9DyZ2ZUFgba-KyOIFrX3JLpeKk0lEEYrUQZCqeesl_jBfrzipcE39uztXDN3HdXmpiDwTwVbC4KqE/s1600/test_results2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5B2_RTlFEZUnrlhNmc67VNayxqAGv2l8t-q95fGK6-b3DsD3fN9_PRkexDz8zQZc9DyZ2ZUFgba-KyOIFrX3JLpeKk0lEEYrUQZCqeesl_jBfrzipcE39uztXDN3HdXmpiDwTwVbC4KqE/s640/test_results2.png" /></a></div>
<br/>
<hr/>
<h1 class="post">Frequently Asked Questions</h1>
<h2 class="post">Where's my Vanilla ObjectContext's AddTo<i>ObjectSetName</i> method gone?</h2>
This method has now been deprecated in <b>Entity Framework 4.0</b>. Instead of using <code>AddTo<i>ObjectSetName</i></code>, use <code><<i>My Vanilla ObjectContext>.<ObjectSetName></i>.AddObject()</code>.
<br/>
<br/>
<h2 class="post">How do I unit test my EDMX EntityObject Functions?</h2>
Functions map to <b>Stored Procedures</b> in your database. You cannot, therefore, unit test your C# code and expect to call an SP as part of the unit test. You'll have to make sure that the high level logic function that calls the stored procedure is not included in your code C# tests; if you can break the function down into smaller method units within the logic class you may still be able to test the smaller logic units that don't require the SP. For unit testing the SP however, you need to create a <b>Database Unit Test</b> project.
<br/>
<br/>
<h2 class="post">How do I perform a unit test that includes database connectivity?</h2>
This, semantically speaking, is not possible. A code <b>Unit Test</b> should be testing units of code. If you need to perform a test across your code into a persistent storage medium, then this is an <b>Integration Test</b>. The Unit Testing phase is performed before the Integration Testing phase.Rabhttp://www.blogger.com/profile/03147240392999345216noreply@blogger.com42tag:blogger.com,1999:blog-3700729221406282508.post-55833234907444808762010-08-19T00:00:00.012+01:002010-08-23T23:27:24.469+01:00Maintenance-Free Mocking for Unit Testing with Entity Framework 4.0If you are trying to unit test in <b>Entity Framework 4.0</b>, you may have come across an apparent lack of architectural support for unit testing integration. <b>Visual Studio 2010</b> appears to have excellent support for integrating Unit Test Projects into your solution, but no out-of-the box integration for using an <b>Entity Framework Data Model (EDMX)</b> generated Object Context is provided.<br />
<br />
This article discusses how to implement a <b>Mocking</b> based approach to <b>Unit Testing</b> in a way that requires <b>zero future code maintenance</b>; generated automatically from the EDMX. The implementation doesn't require anything more than Visual Studio 2010. The finished product is implemented as a self-contained <b>Visual Studio 2010 Item Template</b>, available for download (see bottom of article).<br />
<br />
<h3>Unit Testing & Mocking: A Brief Synopsis</h3>If you want to <b>unit test</b> a Business Logic Layer, the BLL mustn't access the database within any part of the test cycle. If this happens the tests could be "contaminated" with errors from other layers. Additionally this sort of approach, whilst valid for full system testing, increases the overhead of performing the tests; a test database has to be set up, the schema implemented and the data put into a known state. A unit test only deals with testing on the component level, and shouldn't be dependent on persistent data, nor should it persist data itself.<br />
<br />
<b>Mocking</b> is the process of swapping a functional object with a simulated <i>mock object</i> which shares the same interface. In the context of a BLL, this is normally the DAL "facade" or manager class; like your specialised <code>ObjectContext</code> class in <b>Entity Framework</b>. This mock object may then be provided to the test client in the stead of the functional class, and instead of retrieving and persisting data to the database, the mock object will gather data and/or report for testing purposes.<br />
<br />
<h3>The Problem</h3>The issue with attempting to "drop in" a mocking approach in Entity Framework is that your specialised <code>ObjectContext</code> class, the facade class generated from the EDMX, has <b>no generated interface containing the specialised functionality</b>. Without an interface, it's impossible to implement the classical approach to implementing a <b>Mock ObjectContext</b>:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6fLBFi7J4dIypGhbMA4u9nrgv6RNUMCrNpjqxGM_8Rs-G3vAdl6z8zdhYak5tccNgQbfgxIlvEBRK4n1nXzFl4L2ly1SkzKA4DYU1QWRzQ38LZkbZQ2IGnFvWUxufncalLFyl36GHXPcC/s1600/object_context.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6fLBFi7J4dIypGhbMA4u9nrgv6RNUMCrNpjqxGM_8Rs-G3vAdl6z8zdhYak5tccNgQbfgxIlvEBRK4n1nXzFl4L2ly1SkzKA4DYU1QWRzQ38LZkbZQ2IGnFvWUxufncalLFyl36GHXPcC/s640/object_context.png" /></a></div><br />
From the class diagram shown you can see that <code>MyObjectContext</code> derives directly from <code>ObjectContext</code>; the only way to provide a <b>Mock ObjectContext</b> using the out-of-the-box architecture would be either a reflection or proxy-based approach, or by completely overriding the functionality in the base class (creating a <i>refused bequest</i> smell). All undesirable as they are complicated, potentially more error prone, and more difficult for a new developer on the team to pick up as they don't follow the classical Mocking approach.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><script type="text/javascript"><!--
google_ad_client = "pub-0512119130938677";
/* 728x90, In post */
google_ad_slot = "4302000319";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
</div><br />
<h3>The Solution</h3>The solution is very simple, thanks to the new <b>T4 (Text Template Transformation Toolkit)</b> integration provided in <b>Entity Data Modeller</b> in <b>Entity Framework 4.0</b>. For the uninitiated, T4 is what is already used to generate your specialised <code>ObjectContext</code> and <code>EntityObject</code> classes from your <b>EDMX</b> file behind the scenes.<br />
<br />
By using T4 we can instead come up with the following generated architecture, with very few changes to the out-of-the-box solution:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDcw2PowW3Q0_OxAn0htc8XbeB-GfU1coxkKxYlf77VqRvU-GHSDeX89zQf6kJya7NLviSdHEtuGtbcskwxXPLkvHTslOSNHagTjhDZSSEKv5ORvanSguBdeLScD6EnykclGelSwHNyxn7/s1600/object_context_interface.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDcw2PowW3Q0_OxAn0htc8XbeB-GfU1coxkKxYlf77VqRvU-GHSDeX89zQf6kJya7NLviSdHEtuGtbcskwxXPLkvHTslOSNHagTjhDZSSEKv5ORvanSguBdeLScD6EnykclGelSwHNyxn7/s640/object_context_interface.png" /></a></div><br />
Note that <code>MyObjectContext</code> now implements <code>IMyObjectContext</code>. This allows the implementation of the <code>MockMyObjectContext</code>, and for it to share the same interface. This interface is passed to business logic clients instead of the concrete contexts, so that they are unaware if they are talking to the database, or instead being unit tested.<br />
<br />
<h3>Download and Instructions</h3>The download link and (very simple) guide to using is available <a href="http://blogofrab.blogspot.com/2010/08/mocking-context-generator-visual-studio.html">here</a>.<br />
<br />
<hr /><h3>Thoughts and Considerations</h3>Change Tracking and EntityObject<br />
You may have noticed that the strongly typed entity object now derives from Object instead of EntityObject. This is because the entity object is now implemented as a POCO object as the complex change tracking interferes with the mocking. However, Entity Framework 4.0 employs generated proxy classes to manage change tracking if POCO objects' properties are implemented as virtual. See <a href="http://blogs.msdn.com/b/adonet/archive/2009/05/28/poco-in-the-entity-framework-part-2-complex-types-deferred-loading-and-explicit-loading.aspx">POCO in the Entity Framework</a>.<br />
<br />
ObjectQuery<T> Include<br />
In the mocking context, ObjectSet<T> can no longer be used as this is a concrete object that liaises with the database. The context interface instead generates collections of type IObjectSet<T>, and both the concrete functional context and the mocking context implement this. <br />
<br />
However, because ObjectSet<T> derives from ObjectQuery<T> this means we lose Include. To provide a workaround, the T4 generator implements an extension class for the interface IQueryable, that provides an Include method. This should mean that you can continue to use your existing code without any changes.<br />
<br />
The workaround used was taken from <a href="http://thedatafarm.com/blog/data-access/agile-entity-framework-4-repository-part-5-iobjectset">Julie Lerman's Blog</a>.Rabhttp://www.blogger.com/profile/03147240392999345216noreply@blogger.com28tag:blogger.com,1999:blog-3700729221406282508.post-89177130127287937772010-08-18T23:56:00.014+01:002010-08-23T20:35:37.723+01:00ADO.NET Mocking Context Generator: Visual Studio 2010 TemplateIn my <a href="http://blogofrab.blogspot.com/2010/08/maintenance-free-mocking-for-unit.html">previous article</a>, I discussed how to put together a <b>Visual Studio 2010 Template</b> to provide Maintenance-free Mocking for Unit Testing in <b>Entity Framework 4.0</b>.<br />
<br />
The template is available for download from Microsoft, <a href="http://visualstudiogallery.msdn.microsoft.com/en-us/a850e686-df08-4245-b0bb-5872654285c9">here</a>.<br />
<br />
You can also download it using <b>Visual Studio 2010</b>, by selecting <b>Online Templates</b> from the <b>Add New Item</b> dialog.<br />
<br />
<h3>How to Use</h3>Just like any other <b>Entity Framework Artifact Generator</b>, after installing:<br />
<li/>Open your <b>Entity Framework Model (EDMX)</b> file<br />
<li/>Right click the background and press <b>Properties</b><br />
<li/>Set <b>Code Generation Strategy</b> to <b>None</b>.<br />
<li/>Right click the background again, and select <b>Add Code Generation Item</b><br />
<li/>From the <b>Add New Item</b> dialog, select <b>ADO.NET Mocking Context Generator</b><br />
<br />
At some point I might extend this page to include a brief guide to unit testing. Until then, <a href="http://thedatafarm.com/blog/data-access/agile-entity-framework-4-repository-part-6-mocks-amp-unit-tests/">Julie Lerman's Blog</a> is a good resource, along with the <a href="http://blogs.msdn.com/b/adonet/archive/2009/12/17/walkthrough-test-driven-development-with-the-entity-framework-4-0.aspx">ADO.NET Team Blog</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><script type="text/javascript"><!--
google_ad_client = "pub-0512119130938677";
/* 728x90, In post */
google_ad_slot = "4302000319";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
</div>Rabhttp://www.blogger.com/profile/03147240392999345216noreply@blogger.com0tag:blogger.com,1999:blog-3700729221406282508.post-9005953017181045962010-08-09T23:58:00.008+01:002010-08-13T15:33:19.572+01:00Stateless paging in SQL Server CE 3.51 using Entity FrameworkIf you are bound to <b>Microsoft SQL Server Compact Edition 3.51</b> (or indeed, I think any of 3.x) using <b>Entity Framework</b> then you may have found the lack of support for server-stateless paging through queries:<br />
<pre><span style="color: blue;">SELECT VALUE</span> employee
<span style="color: blue;">FROM</span> Employees
<span style="color: blue;">ORDER BY</span> employee.Name
<span style="color: blue;">SKIP</span>(<span style="color: #2b91af;">@skip</span>) <span style="color: blue;">LIMIT</span> (<span style="color: #2b91af;">@limit</span>)
</pre>Both the <b>LINQ Skip()</b> and <b>Take()</b> extensions, along with the Entity SQL commands <b>SKIP</b> and <b>LIMIT</b> commands all come back with runtime errors.<br />
<br />
<h3>Paging with TOP</h3>This is an alternative SQL keyword that can be employed in <b>SQL Server 3.51 CE</b>. Normally it provides a function similar to <b>LIMIT</b>, although has no equivalent to <b>SKIP</b>, which makes it pretty useless. However, with a bit of fudging, it's possible to come up with an Entity SQL query that does the same thing:<br />
<br />
<pre><span style="color: blue;">SELECT VALUE</span> skip_query <span style="color: blue;">FROM</span>
(
<span style="color: blue;">SELECT VALUE TOP</span> (<span style="color: #2b91af;">@count</span>) take_query
<span style="color: blue;">FROM</span>
(
<span style="color: blue;">SELECT VALUE TOP</span>(<span style="color: #2b91af;">@end</span>) employee
<span style="color: blue;">FROM</span> Company.Employees <span style="color: blue;">AS</span> employee
<span style="color: blue;">ORDER BY</span> employee.Name <span style="color: blue;">ASC</span>, employee.Id <span style="color: blue;">ASC</span>
)
<span style="color: blue;">AS</span> take_query
<span style="color: blue;">ORDER BY</span> take_query.Name <span style="color: blue;">DESC</span>, employee.Id <span style="color: blue;">DESC</span>
)
<span style="color: blue;">AS</span> skip_query
<span style="color: blue;">ORDER BY</span> skip_query.Name <span style="color: blue;">ASC</span>, employee.Id <span style="color: blue;">ASC</span>;
</pre><br />
<h3>Considerations</h3>Admittedly, we've got the parameters <b>count</b> and <b>end</b> to use, so it's not <i>exactly</i> the same as <b>SKIP</b> and <b>LIMIT</b>, but it works just as well.<br />
<br />
If you're worried about efficiency, the improvements of properly paging should vastly overcome the use of nested statements and their performance impact on CE.<br />
<br />
Also, if you look at the <a href="http://msdn.microsoft.com/en-us/library/bb738522.aspx">documentation</a> for <b>TOP</b> it does give a warning that it's non-deterministic. However note that as long as an <b>ORDER BY</b> clause is specified, this is negated. <b>Do however note</b> that each record must have a unique placement in the <b>ORDER BY</b> clause. I highly recommend putting the primary key as a secondary ordered field to ensure deterministicity, as shown in the example above.<br />
<br />
<br />
<br />
<h3>Source Code</h3>There's more than one way to implement an <b>Entity SQL Query</b>, but if you want implicit object materialisation, then using an <b>ObjectQuery</b> instance is the easiest way.<br />
<br />
<pre style='color:#000000'><span style='color:#0000ff'>private const string</span> SkipLimitQuery = <span style='color:#a31515'>"SELECT VALUE skip_query..."</span>;
<span style='color:#0000ff'>private</span><span style='color:#2b91af'> Employee</span>[] GetEmployeesPaged( <span style='color:#0000ff'>int</span> start, <span style='color:#0000ff'>int</span> count )
{
<span style='color:#0000ff'>using</span> ( <span style='color:#2b91af'>Company</span> context = <span style='color:#0000ff'>new</span><span style='color:#2b91af'> Company</span>() )
{
<span style='color:#2b91af'>ObjectQuery</span><DAL.<span style='color:#2b91af'>Rom</span>> query = context.CreateQuery<<span style='color:#2b91af'>Employee</span>>( SkipLimitQuery );
command.Parameters.Add( <span style='color:#0000ff'>new</span><span style='color:#2b91af'> ObjectParameter</span>( <span style='color:#a31515'>"count"</span>, count ) );
command.Parameters.Add( <span style='color:#0000ff'>new</span><span style='color:#2b91af'> ObjectParameter</span>( <span style='color:#a31515'>"end"</span>, start + count ) );
<span style='color:#0000ff'>return</span> query.ToArray();
}
}</pre>Rabhttp://www.blogger.com/profile/03147240392999345216noreply@blogger.com2tag:blogger.com,1999:blog-3700729221406282508.post-74851961335958834542010-06-20T09:46:00.094+01:002010-06-22T15:57:21.437+01:00A Strongly Typed Expand Extension for WCF Data Services ClientsFor anyone that's used <strong>WCF Data Services </strong>(formerly <strong>ADO.NET Data Services</strong>), I guess you'll have run into the fact that using the <strong><span style="font-family: inherit;">Expand</span></strong> function for eager loading tables referenced by foreign keys uses a string as its overhead parameter:<br />
<pre><span style="color: #2b91af;">DataServiceQuery</span><span style="color: purple;"><</span><span style="color: #2b91af;">Car</span><span style="color: purple;">></span><span style="color: black;"> query </span><span style="color: purple;">=</span><span style="color: black;"> myDataServiceContext</span><span style="color: purple;">.</span><span style="color: black;">Cars</span><span style="color: purple;">.</span><span style="color: black;">Expand( </span><span style="color: #a31515;">"Wheels"</span><span style="color: black;"> );</span></pre>I was always really confused with this. This is what it's like in <strong>Entity Framework 4.0</strong> as well with the <strong>Include</strong> function. Using a string literal of course means that schema changes will not be picked up at compile time. The code will successfully be compiled if the "Wheels" table has changed its name for instance, and the problem only gets picked up in the testing phase.</p><br />
<h3>A type safe approach</h3>So here's the code that I use. It's an extension class, so you can carry on using your existing data context object, and is not overtly "code-intrusive". It provides the ability to use strongly typed expressions instead of magic strings. When your schema changes, a compile error will be raised displaying that the foreign table name is no longer correct. This will of course make an automated build fail, which is exactly what we want.<br />
<pre><span style="color: black;"></span><span style="color: blue;">using</span><span style="color: black;"> DataServiceQueryExpressions;</span>
...
<span style="color: #2b91af;">DataServiceQuery</span><span style="color: purple;"><</span><span style="color: #2b91af;">Car</span><span style="color: purple;">></span><span style="color: black;"> query </span><span style="color: purple;">=</span><span style="color: black;"> myDataServiceContext</span><span style="color: purple;">.</span><span style="color: black;">Cars</span><span style="color: purple;">.</span><span style="color: black;">Expand( car => car.Wheels );</span></pre>Note that you can also use the extension for generating cascading expand URIs, along with the ability to specify foreign key references across data collection boundaries, as shown below:<br />
<pre><span style="color: #2b91af;">DataServiceQuery</span><span style="color: purple;"><</span><span style="color: #2b91af;">Car</span><span style="color: purple;">></span><span style="color: black;"> query </span><span style="color: purple;">=</span><span style="color: black;"> myDataServiceContext</span><span style="color: purple;">.</span><span style="color: black;">Cars;</span>
query = query<span style="color: purple;">.</span><span style="color: black;">Expand( car => car.Engine );</span>
query = query<span style="color: purple;">.</span><span style="color: black;">Expand( car => car.Engine.Manfucturer );
query = query<span style="color: purple;">.</span><span style="color: black;">Expand( car => car.Wheels );</span>
query = query</span><span style="color: purple;">.</span><span style="color: black;">Expand( car => car.Wheels.First().Tyre );</span>
</pre><br />
<h3>Source code</h3>Copy and paste the following code into a new class (.cs) file. Use the namespace from your business logic layer, and start expanding safely.<br />
<pre style='color:#000000'><span style='color:#008000'>// Rab Hallett 2009. Public Domain.
// Whilst I'd appreciate if you could keep my name at the top of this source code,
// I won't be mad at you if you rip it off and pass it off to your boss as your own.</span>
<span style='color:#0000ff'>using</span> System;
<span style='color:#0000ff'>using</span> System.Text;
<span style='color:#0000ff'>using</span> System.Linq.Expressions;
<span style='color:#0000ff'>using</span> System.Data.Services.Client;
<span style='color:#0000ff'>namespace</span> DataServiceQueryExpressions
{
<span style='color:#808080'>/// <summary>
///</span><span style='color:#008000'> Extension for the </span><span style='color:#808080'><code></span><span style='color:#008000'>DataServiceQuery</span><span style='color:#808080'></code></span><span style='color:#008000'> class that supplies an </span><span style='color:#808080'>
///</span><span style='color:#008000'> override for the </span><span style='color:#808080'><code></span><span style='color:#008000'>Expand</span><span style='color:#808080'></code></span><span style='color:#008000'> function, allowing query expand </span><span style='color:#808080'>
///</span><span style='color:#008000'> paths to be specified by strongly typed expressions as opposed to </span><span style='color:#808080'>
///</span><span style='color:#008000'> magic strings.</span><span style='color:#808080'>
/// <example>
///</span><span style='color:#008000'> myObjectContext.MyNamedEntityCollection.Expand( x => x.ForeignKeyTable );</span><span style='color:#808080'>
/// </example>
/// </summary></span><span style='color:#0000ff'>
public static class</span><span style='color:#2b91af'> ExpressionsExtension</span>
{
<span style='color:#808080'>/// <summary>
///</span><span style='color:#008000'> Specifies the related objects to include in the query results.</span><span style='color:#808080'>
/// </summary>
/// <returns></span><span style='color:#008000'>A new System.Data.Objects.ObjectQuery</span><span style='color:#808080'><T></span><span style='color:#008000'> with the defined </span><span style='color:#808080'>
///</span><span style='color:#008000'> query path.</span><span style='color:#808080'></returns></span><span style='color:#0000ff'>
public static</span><span style='color:#2b91af'> DataServiceQuery</span><T> Expand<T>
(<span style='color:#0000ff'>this</span><span style='color:#2b91af'> DataServiceQuery</span><T> parent, <span style='color:#2b91af'>Expression</span><<span style='color:#2b91af'>Func</span><T, <span style='color:#0000ff'>object</span>>> expression)
{
<span style='color:#0000ff'>if</span> ( expression.Body.NodeType != <span style='color:#2b91af'>ExpressionType</span>.MemberAccess )
{
<span style='color:#0000ff'>throw new</span><span style='color:#2b91af'> ArgumentException</span>( <span style='color:#a31515'>"expected a member access node for the "</span> +
<span style='color:#a31515'>"expression body."</span> );
}
<span style='color:#0000ff'>const char</span> PathSeparator = <span style='color:#a31515'>'/'</span>;
<span style='color:#008000'>// Get the last element of the include path</span><span style='color:#2b91af'>
MemberExpression</span> expressionBody = (<span style='color:#2b91af'>MemberExpression</span>)expression.Body;
<span style='color:#2b91af'>StringBuilder</span> path = <span style='color:#0000ff'>new</span><span style='color:#2b91af'> StringBuilder</span>();
<span style='color:#0000ff'>do</span>
{
<span style='color:#008000'>// Build the next component of the include path</span><span style='color:#0000ff'>
if</span> ( path.Length > 0 )
{
path.Insert( 0, PathSeparator );
}
path.Insert( 0, expressionBody.Member.Name );
<span style='color:#008000'>// Get the next expression node; throw if not a call or method type</span><span style='color:#2b91af'>
Expression</span> nextNode = expressionBody.Expression;
<span style='color:#0000ff'>if</span> ( nextNode.NodeType != <span style='color:#2b91af'>ExpressionType</span>.Call &&
nextNode.NodeType != <span style='color:#2b91af'>ExpressionType</span>.MemberAccess &&
nextNode.NodeType != <span style='color:#2b91af'>ExpressionType</span>.Parameter )
{
<span style='color:#0000ff'>throw new</span><span style='color:#2b91af'> InvalidOperationException</span>(
<span style='color:#a31515'>"Unsupported node specified in expression: "</span> + nextNode.NodeType );
}
<span style='color:#008000'>// Skip any superfluous method calls (like First()): these are required
// for including through collection (eg. MyARecords.First().MyBRecord) </span><span style='color:#0000ff'>
while</span> ( nextNode.NodeType == <span style='color:#2b91af'>ExpressionType</span>.Call )
{
nextNode = ( (<span style='color:#2b91af'>MethodCallExpression</span>)nextNode ).Arguments[ 0 ];
}
<span style='color:#008000'>// Get the next member expression, if any</span>
expressionBody = nextNode <span style='color:#0000ff'>as</span><span style='color:#2b91af'> MemberExpression</span>;
}
<span style='color:#0000ff'>while</span> ( expressionBody != <span style='color:#0000ff'>null</span> );
<span style='color:#008000'>// Call the underlying framework function with the path string</span><span style='color:#0000ff'>
return</span> parent.Expand( path.ToString() );
}
}
}</pre>Rabhttp://www.blogger.com/profile/03147240392999345216noreply@blogger.com5