Using Entity Framework's New POCO Features: Part 2 (Unit Testing)  Presented by Jamie Phillips http://devblog.petrellyn.com
Who is Jamie Phillips Senior Software Engineer with over 10 years experience in the Telecomm, e Commerce, Finance and Healthcare industries. Passionate about working with the .NET framework and related technologies (C# 3.5, WCF, Entity Framework, etc.) Natural ability to adapt to change has lead to becoming a practicing SCRUM Master and evangelist.
 
Unit Testing or Integration Testing? Unit Tests: test an individual unit of code in isolation “ stub out” or “mock” dependencies (e.g. DB, config files) Integration Tests: test “across code boundaries or architectural layers” test as much of the code stack as feasibly possible (from UI to Data resource) Most tests labeled as Unit Tests are actually Integration Tests.
The Restaurant Analogy: Unit versus Integration Tests (Roy Osherove)
It is  not  a Unit Test if: Communicates with a database Communicates across a network Interacts with the file system E.g. reading / writing configuration files Cannot run at the same time as any other unit test Special “environmental considerations” required prior to running E.g. editing configuration files, editing environment variables.
How can  true  unit testing be achieved? Through the application of  Dependency Injection Pattern , “true unit testing” can be achieved for the majority of cases. 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. Code refactoring is inevitable; think of it as the “cleansing pain” – once it is done, the healing can begin.
What is Dependency Injection (DI)? Dependency Injection  is a  design pattern  based on the theory of “separation of concerns”. An object instance will have its resource-based member variables (database connectivity, file system interaction, etc) [ Dependency ] set by an external entity [ Injection ] Often referred to as IoC (Inversion of Control) – a common mistake made – IoC is a container/implementation of the Dependency Injection pattern.
Types of Dependency Injection Setter Injection Class with no argument-constructor which creates the object with "reasonable-default“ properties. The user of the object can then call setters on the object to override these "reasonable-default“ properties. public class  Manager { IEFWorkshopContext _context; public Manager( ) { _context =  new  EFWorkshopContext(); } public  IEFWorkshopContext  Context { get  { _context =  value ; } } }
Types of Dependency Injection (cont) Constructor Injection (Preferred) Class needs to declare a constructor that includes everything it needs injected. With Constructor Injection enforces the order of initialization and prevents circular dependencies public class  Manager { IEFWorkshopContext _context; public Manager( ) { _context =  new  EFWorkshopContext(); } public Manager( IEFWorkshopContext i_context) { _context = i_context; } }
DI is only one half of the equation Dependency Injection will facilitate better and truer Unit Tests, but it is not all that is needed. In order to “mimic” the external dependencies mocking can be utilized. Mocking  can be achieved through the use of custom code or (more preferably) the use of a  mocking framework.
What is Mocking? Mocking is only one pattern from four particular kinds of “ Test Doubles ”: Dummy  objects are passed around but never actually used. Usually they are just used to fill parameter lists. Fake  objects actually have working implementations, but usually take some shortcut which makes them not suitable for production. 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'. 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.
How does this all fit in with EF? 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. By supporting POCO separation of concerns can easily be achieved in EF 4.0; the secret is in the use of  IObjectSet < T >
How does this fit together? Object Instances (class under test) Mock Objects (injected dependency) Dummy Data
Now what? Identify Dependencies 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> : 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; } }
Now what? Create Default Class The default class is the one that will really do the connectivity to the DB, sub classing from  ObjectContext : 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;) { } ...
Now what? Create  IObjectSet<T>  Properties In each of the get properties, instantiate the instance of the  IObjectSet<T>  via the  CreateObjectSet< T>()  method: private  IObjectSet<Address> _Addresses; public  IObjectSet<Address> Addresses { get  { return _Addresses ??  (_Addresses = CreateObjectSet< Address>()); } }
Now what? Create Manager Class The “manager” class will utilize the Dependency Injection pattern to permit “swapping” out of the identified interfaces: 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(); }
Now what? Prepare for mocks Use Extension method in Unit Test to “translate”  List <T>  of entities to  IObjectSet <T>  that will be used with the mocking framework: public static class  ObjectSetExtension { public static  IObjectSet<T> AsObjectSet<T>( this  List<T> entities) where T : class { return new  MockObjectSet<T>(entities); } }
Now what? Writing the Test Method  - Arrange Avoid Record-Replay and use Arrange, Act, Assert (AAA) – it reflects what we do with objects. Arrange  – prepare all of the necessary actual and mock instances // - 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;
Now what? Writing the Test Method - Act Act – by calling the method on the object under test to (later) verify it’s behavior: // - ACT - try { person = manager.GetPerson(id); } catch  ( Exception  exc) { expectedExc = exc; }
Now what? Writing the Test Method - Assert Assert  – that the actions performed yielded the desired result: // - 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; });
Putting it together... Application of DI and use of the Rhino Mocks and MSTest Unit testing frameworks.
Code Coverage Another facet of Unit Testing is the analysis of code coverage. Provides very good feedback on the areas of code that are being tested. Does not tell you how reliable the code is. Integrated with Visual Studio Team Edition or Test Edition.
Demonstration on Code Coverage
DI oh my! Dependency Injection does not only lend itself to better unit testing it provides many more advantages: Separation of concerns improves maintainability of code through the fact that dependencies can be clearly identified and therefore be replaced / refactored more easily. Flexible / pluggable architecture more easily adopted, especially through the use of IoC frameworks such as Unity and StructureMap; because they are based upon DI. Design is made cleaner; clear boundaries set between units of code.
Questions and Answers
ADDITIONAL MATERIAL Dependency Injection and Mocking
Which Unit Testing frameworks? Comparisons between NUnit 2.x, MbUnit 2.4, MSTest and xUnit.net: http://www.codeplex.com/xunit/Wiki/View.aspx?title=Comparisons NUnit Command-line + UI Open source currently at 2.4.8 MbUnit Command-line + UI Open source currently at 3.0.6 MSTest Integrated with VS2008 Team or Test edition (can be run from command-line as well) Code-coverage reporting integrated in Visual Studio xUnit.net Command-line Open source currently at 1.1
What Mocking frameworks are available for .NET? NMock2 Licensed under BSD  Currently 2.0 RC (Jan 30, 2008) Moq Licensed under BSD  Currently 3.1.416 (Apr 16, 2009) RhinoMocks Licensed under BSD  Currently 3.5 RC (Oct 4, 2008) TypeMock Commercial product  Currently 5.3.0 (Jan 13, 2009)
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.

Ef Poco And Unit Testing

  • 1.
    Using Entity Framework'sNew POCO Features: Part 2 (Unit Testing) Presented by Jamie Phillips http://devblog.petrellyn.com
  • 2.
    Who is JamiePhillips Senior Software Engineer with over 10 years experience in the Telecomm, e Commerce, Finance and Healthcare industries. Passionate about working with the .NET framework and related technologies (C# 3.5, WCF, Entity Framework, etc.) Natural ability to adapt to change has lead to becoming a practicing SCRUM Master and evangelist.
  • 3.
  • 4.
    Unit Testing orIntegration Testing? Unit Tests: test an individual unit of code in isolation “ stub out” or “mock” dependencies (e.g. DB, config files) Integration Tests: test “across code boundaries or architectural layers” test as much of the code stack as feasibly possible (from UI to Data resource) Most tests labeled as Unit Tests are actually Integration Tests.
  • 5.
    The Restaurant Analogy:Unit versus Integration Tests (Roy Osherove)
  • 6.
    It is not a Unit Test if: Communicates with a database Communicates across a network Interacts with the file system E.g. reading / writing configuration files Cannot run at the same time as any other unit test Special “environmental considerations” required prior to running E.g. editing configuration files, editing environment variables.
  • 7.
    How can true unit testing be achieved? Through the application of Dependency Injection Pattern , “true unit testing” can be achieved for the majority of cases. 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. Code refactoring is inevitable; think of it as the “cleansing pain” – once it is done, the healing can begin.
  • 8.
    What is DependencyInjection (DI)? Dependency Injection is a design pattern based on the theory of “separation of concerns”. An object instance will have its resource-based member variables (database connectivity, file system interaction, etc) [ Dependency ] set by an external entity [ Injection ] Often referred to as IoC (Inversion of Control) – a common mistake made – IoC is a container/implementation of the Dependency Injection pattern.
  • 9.
    Types of DependencyInjection Setter Injection 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. public class Manager { IEFWorkshopContext _context; public Manager( ) { _context = new EFWorkshopContext(); } public IEFWorkshopContext Context { get { _context = value ; } } }
  • 10.
    Types of DependencyInjection (cont) Constructor Injection (Preferred) Class needs to declare a constructor that includes everything it needs injected. With Constructor Injection enforces the order of initialization and prevents circular dependencies public class Manager { IEFWorkshopContext _context; public Manager( ) { _context = new EFWorkshopContext(); } public Manager( IEFWorkshopContext i_context) { _context = i_context; } }
  • 11.
    DI is onlyone half of the equation Dependency Injection will facilitate better and truer Unit Tests, but it is not all that is needed. In order to “mimic” the external dependencies mocking can be utilized. Mocking can be achieved through the use of custom code or (more preferably) the use of a mocking framework.
  • 12.
    What is Mocking?Mocking is only one pattern from four particular kinds of “ Test Doubles ”: Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists. Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production. 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'. 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.
  • 13.
    How does thisall fit in with EF? 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. By supporting POCO separation of concerns can easily be achieved in EF 4.0; the secret is in the use of IObjectSet < T >
  • 14.
    How does thisfit together? Object Instances (class under test) Mock Objects (injected dependency) Dummy Data
  • 15.
    Now what? IdentifyDependencies 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> : 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; } }
  • 16.
    Now what? CreateDefault Class The default class is the one that will really do the connectivity to the DB, sub classing from ObjectContext : 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;) { } ...
  • 17.
    Now what? Create IObjectSet<T> Properties In each of the get properties, instantiate the instance of the IObjectSet<T> via the CreateObjectSet< T>() method: private IObjectSet<Address> _Addresses; public IObjectSet<Address> Addresses { get { return _Addresses ?? (_Addresses = CreateObjectSet< Address>()); } }
  • 18.
    Now what? CreateManager Class The “manager” class will utilize the Dependency Injection pattern to permit “swapping” out of the identified interfaces: 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(); }
  • 19.
    Now what? Preparefor mocks Use Extension method in Unit Test to “translate” List <T> of entities to IObjectSet <T> that will be used with the mocking framework: public static class ObjectSetExtension { public static IObjectSet<T> AsObjectSet<T>( this List<T> entities) where T : class { return new MockObjectSet<T>(entities); } }
  • 20.
    Now what? Writingthe Test Method - Arrange Avoid Record-Replay and use Arrange, Act, Assert (AAA) – it reflects what we do with objects. Arrange – prepare all of the necessary actual and mock instances // - 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;
  • 21.
    Now what? Writingthe Test Method - Act Act – by calling the method on the object under test to (later) verify it’s behavior: // - ACT - try { person = manager.GetPerson(id); } catch ( Exception exc) { expectedExc = exc; }
  • 22.
    Now what? Writingthe Test Method - Assert Assert – that the actions performed yielded the desired result: // - 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; });
  • 23.
    Putting it together...Application of DI and use of the Rhino Mocks and MSTest Unit testing frameworks.
  • 24.
    Code Coverage Anotherfacet of Unit Testing is the analysis of code coverage. Provides very good feedback on the areas of code that are being tested. Does not tell you how reliable the code is. Integrated with Visual Studio Team Edition or Test Edition.
  • 25.
  • 26.
    DI oh my!Dependency Injection does not only lend itself to better unit testing it provides many more advantages: Separation of concerns improves maintainability of code through the fact that dependencies can be clearly identified and therefore be replaced / refactored more easily. Flexible / pluggable architecture more easily adopted, especially through the use of IoC frameworks such as Unity and StructureMap; because they are based upon DI. Design is made cleaner; clear boundaries set between units of code.
  • 27.
  • 28.
    ADDITIONAL MATERIAL DependencyInjection and Mocking
  • 29.
    Which Unit Testingframeworks? Comparisons between NUnit 2.x, MbUnit 2.4, MSTest and xUnit.net: http://www.codeplex.com/xunit/Wiki/View.aspx?title=Comparisons NUnit Command-line + UI Open source currently at 2.4.8 MbUnit Command-line + UI Open source currently at 3.0.6 MSTest Integrated with VS2008 Team or Test edition (can be run from command-line as well) Code-coverage reporting integrated in Visual Studio xUnit.net Command-line Open source currently at 1.1
  • 30.
    What Mocking frameworksare available for .NET? NMock2 Licensed under BSD Currently 2.0 RC (Jan 30, 2008) Moq Licensed under BSD Currently 3.1.416 (Apr 16, 2009) RhinoMocks Licensed under BSD Currently 3.5 RC (Oct 4, 2008) TypeMock Commercial product Currently 5.3.0 (Jan 13, 2009)
  • 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.

Editor's Notes

  • #5 Unit Tests are written to test an individual unit of code in isolation, “stubbing out” or “mocking” dependant resources that exist outside the domain of the code being tested (including but not limited to Database or Configuration Files) Integration Tests are written to test “across code boundaries or architectural layers”; they should test as much of the code stack as feasibly possible, from UI to Data resource.
  • #6 Imagine going to a restaurant with a bunch of your friends. there are some couples there as well as singles. At the end of the meal, it is time to pay. Unit testing is like giving a separate bill to each couple or individual. Each person knows only what they need to pay as well as tip, but do not care what anyone else had, or what the total meal amount is; as long as they pay what they need, they can go home peacefully. Integration testing is like giving one big check to the group, with everyone having to calculate on their own how much they need to pay. Sometimes everyone thinks that it works out, but in the end the total amount may be too high or too low. There is a lot of interaction going on to decide who pays for what and who has already paid. And often some will pay more for what they actually had than if they got their own individual bill.
  • #9 Dependency Injection is a design pattern based on the theory of “separation of concerns”. An object instance will have its resource-based member variables (database connectivity, file system interaction, etc) [ Dependency ] set by an external entity [ Injection ] Often referred to as IoC (Inversion of Control) – a common mistake made – IoC is a container/implementation of the Dependency Injection pattern.
  • #10 With Setter Injection it is not clear in which order things need to be instantiated and when the wiring is done
  • #24 Contrast the “Base” (Before) solution and the “UsingDi” (After) solution. Starting with the Manager classes, notice how the test methods call on the actual isntance of the Manager class and mock out the Dependency. Rhino Mocks works with AAA (Arrange, Act, Assert) so we setup the test and the expectations, call the method and assert the results.
  • #26 Executing a complete build we can view the code coverage results (using the “UsingDi” (After) solution)