Building a Testable Data Access Layer Visual Studio Live Orlando 2010MGB 2003 Building a Testable Data Access Layer Todd Anglin Chief Evangelist, Telerik Level: Intermediate © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
Introductions Chief Evangelist, Telerik Todd Anglin Microsoft MVP ASP Insider President NHDNUG & O’Reilly Author TelerikWatch.com @toddanglin
Testing Data Operations Define “Data Layer” Data Layer Options Build Data Layer Testing Data Operations today’s plan
what is a “data layer”?
Domain Logic (“the code that makes you money”) Data Layer Responsible for talking to “persistence layer” Presentation Web Desktop Service Domain Logic (“the code that makes you money”) Data / Model Persistence Database Cloud XML Etc.
why build a data layer? what’s the benefit?
importance of data layer Decouple application from persistence = easier maintenance = improved testability = greater reusability
Domain Logic (“the code that makes you money”) Presentation Web Desktop Service Domain Logic (“the code that makes you money”) Data Persistence Database Cloud XML Etc.
a good data layer…
Handles all data access Hides implementation Flexible Easy to refactor
a bad data layer is…
Does not centralize data access Makes application very dependent on persistent store Easy* Easy = Easy to build if you’re not careful
how do we build “data layers”?
By Hand Pros POCO YAGNI No-RTFM Cons Time No FM ORM Pros Time Flexible Cons Learning Limits Trust*
popular .NET ORMs Microsoft LinqToSQL Entity Framework Open Source nHibernate Commercial Telerik OpenAccess LLBGenPro EntitySpaces
Build data layer with LinqToSql & EF & OpenAccess Demo
data layer patterns Domain Driven Design (DDD) ActiveRecord Key concepts: Repositories act on model ActiveRecord Key concepts: Model objects act on themselves Data Mapper Key concepts: Objects mapped to tables
Add data access pattern to project Demo
testing the data layer Everything is familiar up to this point. Now the dreaded step may of us avoid: Creating tests for the data layer
A B two testing camps Test Database Mock Database Concepts: Concepts: Test against “real” database Use set-up/tear-down code to create test data Good When… You put lots of logic in your database Concepts: Test against “fake” database Isolates your code from database behavior Good When… You want fast unit tests and you put most logic in code
picking a camp “Test” Database Mocking Pros Pros Cons Cons Unit test Isolate concerns Fast Cons “Hides” issues Does not test database logic “Test” Database Pros Catches more issues Familiar Cons Slow Not a “unit” test Hides issues example = concurrency, auto-gen DB values, etc.
testing considerations What is a unit test? What are other types of testing?
UNIT TEST INTEGRATION TEST FUNCTIONAL TEST “Isolated. Repeatable. Fast.” INTEGRATION TEST “Test interaction between units.” FUNCTIONAL TEST “Test behavior from user perspective.”
Database Communication (ORM, ADO.NET, etc.) mock testing Goal: Test your business logic UI Behaviors Services Business Code Repository Database Communication (ORM, ADO.NET, etc.) Database
mocking Stunt doubles for real objects Look the same on the outside Mocking Tools: JustMock (by Telerik) Isolator (by TypeMock) MOQ (OSS) RhinoMocks (OSS)
AAA mocking pattern //Arrange Set-up your test variables and mocks //Act Execute your code like normal //Assert Verify what happened
DEMO: MOCKING DATABASE Testing L2S with Mock Objects DEMO: MOCKING DATABASE
A Steps for every test: test database Goal: Test your business logic + database behavior Steps for every test: Create database schema + test data (Optional) Test database setup correctly Execute unit test code Verify database behaved correctly
hard parts Creating test schema/data Speed DbUnit In memory database SQL Lite, SQL CE, etc.
rules for test database tests Prior to running tests, schema should be redeployed to test DB (+ test data) Tests should not change existing data Edits, Deletes should be on records created by test Original data should be read-only Tests should not depend on changes from previous tests
DEMO: TESTinG with real DB Creating integration tests to talk to real database DEMO: TESTinG with real DB
should you test your DAL?
Q&A anglin@telerik.com @toddanglin telerikwatch.com
Links 4GuysFromRolla on Testing DAL (2005) http://aspnet.4guysfromrolla.com/articles/040605-1.2.aspx Unit Testing the DAL (Java, but great discussion of DAL data testing) http://www.buunguyen.net/blog/unit-testing-the-data-access-layer.html Roy Osherove on using Mocks for DAL testing http://weblogs.asp.net/rosherove/archive/2003/09/30/29734.aspx SQL Lite project page http://www.sqlite.org/docs.html System.Data.SQLite: http://sqlite.phxsoftware.com/ http://www.mikeduncan.com/sqlite-on-dotnet-in-3-mins/ http://hendryluk.wordpress.com/2008/10/07/data-access-test-with-sqlite/ DbUnit.NET (last updated 2006 – still alpha) http://dbunit-net.sourceforge.net/GettingStarted.html SQL Server Compact 4 CTP1 (2010) http://www.microsoft.com/downloads/details.aspx?FamilyID=0d2357ea-324f-46fd-88fc-7364c80e4fdb&displaylang=en http://robtiffany.com/sql-server-compact/here-comes-sql-server-compact-4-0 SQL Script to clear all tables in database http://www.smallworkarounds.net/2009/02/script-to-delete-all-data-from-sql.html Microsoft.SqlServer.Management.Smo primer http://davidhayden.com/blog/dave/archive/2006/01/27/2774.aspx http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/43e8bc3a-1132-453b-b950-09427e970f31 Multi-tier L2S architecture ideas http://blog.stevensanderson.com/2007/11/29/linq-to-sql-the-multi-tier-story/