• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Ef Poco And Unit Testing
 

Ef Poco And Unit Testing

on

  • 4,341 views

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

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

Statistics

Views

Total Views
4,341
Views on SlideShare
4,306
Embed Views
35

Actions

Likes
3
Downloads
0
Comments
0

3 Embeds 35

http://www.slideshare.net 33
http://www.w3schools.com 1
http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • 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.
  • 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.
  • 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.
  • With Setter Injection it is not clear in which order things need to be instantiated and when the wiring is done
  • 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.
  • Executing a complete build we can view the code coverage results (using the “UsingDi” (After) solution)

Ef Poco And Unit Testing Ef Poco And Unit Testing Presentation Transcript

  • 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.