Using Mocking with Test Driven Development

Download Report

Transcript Using Mocking with Test Driven Development

Using Mock Objects with
Test Driven Development
Justin Kohlhepp
[email protected]
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