Roy Osherove Sela Group ISerializable.com (blog)
About Me Agile Development Consulting Training Mentoring .NET Architecture Practices More..
ArtOfUnitTesting.com
Agenda Unit Testing Vs. Integration Testing To mock or not to mock the DB? Rolling back DB state Restore, Manual load, COM+, XTUnit, System.Transactions Working and testing with DataSets Pure DB tests with DataDude Short song?
Demos Rollbacks: COM+ 1.0 COM+ 1.5 (ServiceConfig) XtUnit MbUnit [DataRollback] MbUnit [SqlDbRestore] TransactionScope Comparing DataSets DataDude DataSet loader with XML file update and delete NHibernate ORM ActiveRecord testing
Why should I care? Automated testing and regressions Data Layer also contains logic! Cost of changes is lowered
What is a Unit-Testable System For each piece of coded logic in the system, a unit test can be written easily enough to verify it works as expected while keeping the PC-COF rules Partial runs are possible Configuration is not needed Consistent pass/fail result Order does not matter Fast
Integration Vs. Unit Test Takes longer Needs configuration Needs large parts or whole system Like a car engine
(and learn to tell the difference)
UI Logic Data Layer DB
Why NOT mock it? You don’t test the DB logic itself Keys Indexes Integrity Rules Security Triggers Etc… DB
Unit testing against MySimpleClass
Rolling back DB Data XML File (semi manual loading) DB Restore Transaction COM+ COM+ 1.5 System.Transactions XtUnit MbUnit
Demo
Resetting an identity column USE pubs GO Delete from mytable GO DBCC CHECKIDENT ('mytable', RESEED, 0) DBCC CHECKIDENT ('mytable', RESEED) GO
Allowing IDENTITY INSERT set IDENTITY_INSERT mytable on..insert set IDENTITY_INSERT mytable off
XML Loading Hard to maintain : when there is parent-child relationships When schema changes
Rolling back using COM+ Test Driven Development with Microsoft.NET (James Newkirk) COM+ == System.EnterpriseServices Distributed Transactions MyObject:ServicedComponent
Serviced Tests MyTestClass:ServicedComponent Transaction MySimpleClass
Serviced Tests On Code with ADO.NET Transactions MyTestClass:ServicedComponent Transaction MySimpleClass Transaction 2 SomeOtherClass
Problems with COM+ Rollback What if you are calling other serviced Components? What if they require a new transaction?
Serviced Tests On Serviced Components MyTestClass:ServicedComponent Transaction [Transaction( Required or supported) MySimpleClass:ServicedComponent SomeOtherClass
Serviced Tests On Serviced Components (RequiresNew) MyTestClass:ServicedComponent Transaction Transaction 2 SomeOtherClass [Transaction (RequiredNew or NotSupported) MySimpleClass:ServicedComponent
COM+ 1.5 MbUnit XtUnit System.Transactions
COM+ 1.0 Vs. 1.5 1.5 requires Win XP SP 2 or higher WinServer 2003 SP1 or higher Otherwise – you have to use 1.0
ServiceConfig ServiceDomain
System.Transactions (.NET 2.0) Using(TransactionScope scope = new TransactionScope) { …do DB work here } Automatic promotion of transactions Very simple syntax None ADO.NET Transaction Distributed Transaction (COM+)
XtUnit Pros Decide per test on rollback behavior Create your own attributes easily Tools.osherove.com
MbUnit features SqlRestore Info: Slow Requires exclusive DB access Rollback Com+ 1.5
XUNIT.NET [AutoRollback] Extensible
Types of data layers Table Data Gateway Row Data Gateway Active Record Data Mapper Book: “Patterns of Enterprise Application Architecture” Martin Fowler
Tests Against NHibernate Based Apps MyTestClass Transaction MyClass NHibernate
Tests Against ActiveRecord MyTestClass Transaction MyActiveCategoryClass NHibernate
Demo
Summary DB Integration tests are necessary Try combination of DB tests Application-integration tests DataDude is your friend! Use frameworks System.Transactions XtUnit MbUnit
A song by Roy Osherove (+ Simon & Garfunkel)
ISerializable.com (blog)
Resources PoEAA Book NHibernate ActiveRecord XtUnit MbUnit NUnit DataDude Database Unit Testing article DataSet compare The Art of Unit Testing Book Roy’s Blog: ISerializable.com