Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Ef Poco And Unit Testing


Published on

True Unit Testing can be achieved in the latest incarnation of the Entity Framework from Microsoft through the use of Dependency Injection and POCO.

Published in: Technology, Education
  • Be the first to comment

Ef Poco And Unit Testing

  1. 1. Using Entity Framework's New POCO Features: Part 2 (Unit Testing) Presented by Jamie Phillips
  2. 2. Who is Jamie Phillips <ul><li>Senior Software Engineer with over 10 years experience in the Telecomm, e Commerce, Finance and Healthcare industries. </li></ul><ul><li>Passionate about working with the .NET framework and related technologies (C# 3.5, WCF, Entity Framework, etc.) </li></ul><ul><li>Natural ability to adapt to change has lead to becoming a practicing SCRUM Master and evangelist. </li></ul>
  3. 4. Unit Testing or Integration Testing? <ul><li>Unit Tests: </li></ul><ul><ul><li>test an individual unit of code in isolation </li></ul></ul><ul><ul><li>“ stub out” or “mock” dependencies (e.g. DB, config files) </li></ul></ul><ul><li>Integration Tests: </li></ul><ul><ul><li>test “across code boundaries or architectural layers” </li></ul></ul><ul><ul><li>test as much of the code stack as feasibly possible (from UI to Data resource) </li></ul></ul><ul><li>Most tests labeled as Unit Tests are actually Integration Tests. </li></ul>
  4. 5. The Restaurant Analogy: Unit versus Integration Tests (Roy Osherove)
  5. 6. It is not a Unit Test if: <ul><li>Communicates with a database </li></ul><ul><li>Communicates across a network </li></ul><ul><li>Interacts with the file system E.g. reading / writing configuration files </li></ul><ul><li>Cannot run at the same time as any other unit test </li></ul><ul><li>Special “environmental considerations” required prior to running E.g. editing configuration files, editing environment variables. </li></ul>
  6. 7. How can true unit testing be achieved? <ul><li>Through the application of Dependency Injection Pattern , “true unit testing” can be achieved for the majority of cases. </li></ul><ul><li>Wherever there is a need for using an external resource (including but not limited to Database, File System, etc.) a candidate for dependency injection exists. </li></ul><ul><li>Code refactoring is inevitable; think of it as the “cleansing pain” – once it is done, the healing can begin. </li></ul>
  7. 8. What is Dependency Injection (DI)? <ul><li>Dependency Injection is a design pattern based on the theory of “separation of concerns”. </li></ul><ul><li>An object instance will have its resource-based member variables (database connectivity, file system interaction, etc) [ Dependency ] set by an external entity [ Injection ] </li></ul><ul><li>Often referred to as IoC (Inversion of Control) – a common mistake made – IoC is a container/implementation of the Dependency Injection pattern. </li></ul>
  8. 9. Types of Dependency Injection <ul><li>Setter Injection </li></ul><ul><ul><li>Class with no argument-constructor which creates the object with &quot;reasonable-default“ properties. The user of the object can then call setters on the object to override these &quot;reasonable-default“ properties. </li></ul></ul>public class Manager { IEFWorkshopContext _context; public Manager( ) { _context = new EFWorkshopContext(); } public IEFWorkshopContext Context { get { _context = value ; } } }
  9. 10. Types of Dependency Injection (cont) <ul><li>Constructor Injection (Preferred) </li></ul><ul><ul><li>Class needs to declare a constructor that includes everything it needs injected. </li></ul></ul><ul><ul><li>With Constructor Injection enforces the order of initialization and prevents circular dependencies </li></ul></ul>public class Manager { IEFWorkshopContext _context; public Manager( ) { _context = new EFWorkshopContext(); } public Manager( IEFWorkshopContext i_context) { _context = i_context; } }
  10. 11. DI is only one half of the equation <ul><li>Dependency Injection will facilitate better and truer Unit Tests, but it is not all that is needed. </li></ul><ul><li>In order to “mimic” the external dependencies mocking can be utilized. </li></ul><ul><li>Mocking can be achieved through the use of custom code or (more preferably) the use of a mocking framework. </li></ul>
  11. 12. What is Mocking? <ul><li>Mocking is only one pattern from four particular kinds of “ Test Doubles ”: </li></ul><ul><ul><li>Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists. </li></ul></ul><ul><ul><li>Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production. </li></ul></ul><ul><ul><li>Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'. </li></ul></ul><ul><ul><li>Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive. </li></ul></ul>
  12. 13. How does this all fit in with EF? <ul><li>In EF 1.0 the separation of concerns was a laborious task; without a mechanism of “disengaging” the Entity Framework to use a mocked repository, Dependency Injection was very crude at best. </li></ul><ul><li>By supporting POCO separation of concerns can easily be achieved in EF 4.0; the secret is in the use of IObjectSet < T > </li></ul>
  13. 14. How does this fit together? <ul><li>Object Instances (class under test) </li></ul><ul><li>Mock Objects (injected dependency) </li></ul><ul><li>Dummy Data </li></ul>
  14. 15. Now what? Identify Dependencies <ul><li>Identify the dependencies that need to be injected. In EF 4.0 this will require creating an interface that exposes the entities as IObjectSet<T> : </li></ul>public interface IEFWorkshopContext { IObjectSet<Address> Addresses { get; } IObjectSet<Beer> Beers { get; } IObjectSet<Brewery> Breweries { get; } IObjectSet<SalesPerson> SalesPeople { get; } IObjectSet<Person> People { get; } IObjectSet<FavoriteBeer> FavoriteBeers { get; } IObjectSet<Customer> Customers { get; } IObjectSet<CustomerType> CustomerTypes { get; } }
  15. 16. Now what? Create Default Class <ul><li>The default class is the one that will really do the connectivity to the DB, sub classing from ObjectContext : </li></ul>public class EFWorkshopContext : ObjectContext, IEFWorkshopContext { /// <summary> /// Initializes a new EFWorkshopEntities object using the /// connection string found in the 'EFWorkshopEntities' /// section of the application configuration file. /// </summary> public EFWorkshopContext() : base( &quot;name=EFWorkshopEntities&quot;, &quot;EFWorkshopEntities&quot;) { } ...
  16. 17. Now what? Create IObjectSet<T> Properties <ul><li>In each of the get properties, instantiate the instance of the IObjectSet<T> via the CreateObjectSet< T>() method: </li></ul>private IObjectSet<Address> _Addresses; public IObjectSet<Address> Addresses { get { return _Addresses ?? (_Addresses = CreateObjectSet< Address>()); } }
  17. 18. Now what? Create Manager Class <ul><li>The “manager” class will utilize the Dependency Injection pattern to permit “swapping” out of the identified interfaces: </li></ul>public class Manager { IEFWorkshopContext _context; public Manager() { Initialize(null); } internal Manager( IEFWorkshopContext i_context) { Initialize(i_context); } private void Initialize( IEFWorkshopContext i_context) { _context = i_context ?? new EFWorkshopContext(); }
  18. 19. Now what? Prepare for mocks <ul><li>Use Extension method in Unit Test to “translate” List <T> of entities to IObjectSet <T> that will be used with the mocking framework: </li></ul>public static class ObjectSetExtension { public static IObjectSet<T> AsObjectSet<T>( this List<T> entities) where T : class { return new MockObjectSet<T>(entities); } }
  19. 20. Now what? Writing the Test Method - Arrange <ul><li>Avoid Record-Replay and use Arrange, Act, Assert (AAA) – it reflects what we do with objects. </li></ul><ul><li>Arrange – prepare all of the necessary actual and mock instances </li></ul>// - ARRANGE - // Create the stub instance IEFWorkshopContext context = MockRepository .GenerateStub <IEFWorkshopContext>(); // Create the out-of-range id int id = -1; // declare instance that we want to &quot;retrieve&quot; Person person; // Create a real instance of the Manager Manager manager = new Manager(context); // declare the expected Exception Exception expectedExc = null;
  20. 21. Now what? Writing the Test Method - Act <ul><li>Act – by calling the method on the object under test to (later) verify it’s behavior: </li></ul>// - ACT - try { person = manager.GetPerson(id); } catch ( Exception exc) { expectedExc = exc; }
  21. 22. Now what? Writing the Test Method - Assert <ul><li>Assert – that the actions performed yielded the desired result: </li></ul>// - ASSERT - // Make absolutely sure that the expected exception type was thrown Assert .IsNotNull(expectedExc); Assert .IsInstanceOfType(expectedExc, typeof ( ArgumentException )); Assert .IsInstanceOfType(expectedExc, typeof ( ArgumentOutOfRangeException )); // Make sure that the method was NOT called. context.AssertWasNotCalled(stub => { var temp = stub.People; });
  22. 23. Putting it together... <ul><li>Application of DI and use of the Rhino Mocks and MSTest Unit testing frameworks. </li></ul>
  23. 24. Code Coverage <ul><li>Another facet of Unit Testing is the analysis of code coverage. </li></ul><ul><li>Provides very good feedback on the areas of code that are being tested. </li></ul><ul><li>Does not tell you how reliable the code is. </li></ul><ul><li>Integrated with Visual Studio Team Edition or Test Edition. </li></ul>
  24. 25. Demonstration on Code Coverage
  25. 26. DI oh my! <ul><li>Dependency Injection does not only lend itself to better unit testing it provides many more advantages: </li></ul><ul><ul><li>Separation of concerns improves maintainability of code through the fact that dependencies can be clearly identified and therefore be replaced / refactored more easily. </li></ul></ul><ul><ul><li>Flexible / pluggable architecture more easily adopted, especially through the use of IoC frameworks such as Unity and StructureMap; because they are based upon DI. </li></ul></ul><ul><ul><li>Design is made cleaner; clear boundaries set between units of code. </li></ul></ul>
  26. 27. Questions and Answers
  27. 28. ADDITIONAL MATERIAL <ul><li>Dependency Injection and Mocking </li></ul>
  28. 29. Which Unit Testing frameworks? <ul><li>Comparisons between NUnit 2.x, MbUnit 2.4, MSTest and </li></ul><ul><li>NUnit </li></ul><ul><ul><li>Command-line + UI </li></ul></ul><ul><ul><li>Open source currently at 2.4.8 </li></ul></ul><ul><li>MbUnit </li></ul><ul><ul><li>Command-line + UI </li></ul></ul><ul><ul><li>Open source currently at 3.0.6 </li></ul></ul><ul><li>MSTest </li></ul><ul><ul><li>Integrated with VS2008 Team or Test edition (can be run from command-line as well) </li></ul></ul><ul><ul><li>Code-coverage reporting integrated in Visual Studio </li></ul></ul><ul><li> </li></ul><ul><ul><li>Command-line </li></ul></ul><ul><ul><li>Open source currently at 1.1 </li></ul></ul>
  29. 30. What Mocking frameworks are available for .NET? <ul><li>NMock2 </li></ul><ul><ul><li>Licensed under BSD </li></ul></ul><ul><ul><li>Currently 2.0 RC (Jan 30, 2008) </li></ul></ul><ul><li>Moq </li></ul><ul><ul><li>Licensed under BSD </li></ul></ul><ul><ul><li>Currently 3.1.416 (Apr 16, 2009) </li></ul></ul><ul><li>RhinoMocks </li></ul><ul><ul><li>Licensed under BSD </li></ul></ul><ul><ul><li>Currently 3.5 RC (Oct 4, 2008) </li></ul></ul><ul><li>TypeMock </li></ul><ul><ul><li>Commercial product </li></ul></ul><ul><ul><li>Currently 5.3.0 (Jan 13, 2009) </li></ul></ul>
  30. 31. Comparison between RhinoMock, Moq, NMock2 and TypeMock Ease of use Cost Likes Dislikes Rhino Mocks Easy due to being strongly-typed, which makes the syntax great and &quot;safe&quot;. Free Strongly typed instancing - no need to use string references. Full AAA support Record / Replay should be implied not expected. Moq Doesn’t use record / replay scenarios! similar to Rhino Mocks Free Similar to Rhino Mocks, with no support for record / replay Creates wrapper of mock instance. NMock Use of strings to call property methods / normal methods. Free Pales to insignificance in contrast to RhinoMocks, Moq or TypeMock Need to use string declarations for instancing. Type Mock Extremely easy to implement mocking because it uses the .NET framework profiler API to monitor an application's execution. Expensive The fact that it &quot;plugs-in&quot; to the CLR and captures type references, means that no code changes need to be done on legacy components. Prohibitively Expensive.