Using Mock Objects with Test Driven Development Justin Kohlhepp jkohlhepp@gmail.com What are mock objects? From Wikipedia: simulated objects that mimic the behavior of real objects in controlled ways Think “crash test dummy” Terminology Mocks, Stubs, Fakes… Whatever! Terminology Unit Tests vs. Integration Tests Why use mocks? • • • • • • • • • Isolate code under test; less fragile tests Difficult to set up dependencies Verify interaction between objects Side effects (sending emails, launching missiles) Abnormal situations (network outages, disk full) Multiple dev streams (actual class doesn’t exist) Non-deterministic results (timezones) Real code too slow (trips to database) Real code interacts with user (i.e. UI) Demo Simple Mocking Scenario moq Basic Syntax http://code.google.com/p/moq/wiki/QuickStart moq Framework http://code.google.com/p/moq/ • • • • • • Pronounced "Mock-you" or just "Mock“ .NET 3.5 or higher Focused on simple, flexible API Does not use record/replay style Open source, BSD license Active project since 2007 Test Lifecycle with Mocks Setup Execute Verify Demo: Advanced moq Features • • • • • • • • Mocking Exceptions Loose vs. Strict Complex argument matching Callbacks Mock concrete classes, Partial Mocks Automatic recursive mocks Mock multiple interfaces Access to protected members Design Considerations – “SOLID” S O L I D Single responsibility principle, an object should have only a single responsibility Open/closed principle, open for extension, but closed for modification Liskov substitution principle, derived class should not break assumptions or behavior of base class Interface segregation principle, many specific interfaces are better than one general purpose interface (e.g. role interface) Dependency inversion principle, Depend upon abstractions, not upon concretions Managing Dependencies • “new” keyword prevents isolation • Inversion of Control: class no longer controls its dependencies; no more “new” • Key patterns for IoC: Dependency Injection, Service Locator Demo Dependency Injection Dependency Injection Frameworks • Allow for externalizing dependency management • Can be configuration driven or code driven • Many choices: MS Unity, Castle Windsor, StructureMap, Ninject, etc. Demo “Realistic” Mocking Scenario moq – Under the Hood • Uses Castle DynamicProxy • Creates class on the fly that implements interface or derives from class • Tracks methods, properties that are setup on the mock, and how they are invoked during test execution Other Mocking Frameworks RhinoMocks •Most widely used •Complex API •Too many options TypeMock •More powerful •Different design •Not free Mocking Pitfalls • • • • Gaps in integration testing Maintenance concerns Testing influencing design Tests are very “white box” – they know a lot about the thing they are testing • To verify or not to verify • Heisenbugs • Controversy Conclusions • Mock objects are a powerful tool that you should have in your testing toolbox • Injecting mock objects requires some design considerations. Luckily this also leads to better code (according to some). • Remember: a hybrid approach is possible. Mock some things and use real instances of others. • With great power comes great responsibility Useful Links • Wikipedia: Mock Objects http://bit.ly/7WWq9 • Fowler: Mocks Aren’t Stubs http://bit.ly/7MdzF • QuickStart with moq http://bit.ly/13FYvA • Working Effectively with Legacy Code by Michael Feathers http://amzn.to/Mf59m