3. 3
copyright 2008 trainologic LTD
• The JUnit testing framework, makes the testing of an
independent, non-void method, simple.
• But... how do we test an method with no return value?
• How do we test a method that interacts with other
domain objects?
Testing Mediator Objects
3
Mediator Objects & Testing
4. 4
copyright 2008 trainologic LTD
Mediator Objects & Testing
• Dependencies – In order for a function to run it often
requires Files, DB, JNDI or generally – other units
• Side effects – As a function runs we are often interested
in data written to files, saved to db or generally –
passed to other units
How can we test a single unit, without being
affected by other units – their errors, set-up
complexities and performance issues?
In Real-Life Units are NOT Totally
Self Contained
4
5. 5
copyright 2008 trainologic LTD
• Let’s say we want to test a method that gets an
Account and a Financial Transaction, checks whether
the Transaction is legitimate and only if it is, applies it
to the Account.
• How would you implement this test?
Testing Mediator Objects
5
Mediator Objects & Testing
6. 6
copyright 2008 trainologic LTD
• What if the method receives an Account and prints
specific parts of it using a Logger?
Testing Mediator Objects
6
Mediator Objects & Testing
7. 7
copyright 2008 trainologic LTD
• Many business objects that are really important to test
are mediators, i.e., they contain methods which interact
with other domain objects.
• Since in unit testing we want to test a unit without its
dependencies, we will have to eliminate them somehow.
• We do this by passing dummy objects to “fill in” for the
real dependencies.
Testing Mediator Objects
7
Mediator Objects & Testing
9. 9
copyright 2008 trainologic LTD
• A Stub is a test-only object which:
• Implements the same interface as the production
object
• Gives the set of services used by the tested unit –
often using a naïve, hard-coded implementation
• More complex stubs may even contain test-supporting
logic, e.g. assert that they are used correctly
What is a Stub?
9
Stubs
10. copyright 2008 trainologic LTD
• BookInventory is a package for management of … book
inventories.
• It does inventory management, connection to book
catalogs (like library of congress), etc.
Exercise 1- BookInventory
Stubs
11. 11
copyright 2008 trainologic LTD
• Main Classes
Exercise 1- BookInventory
11
Stubs
1111
BookInventory
Main entry point
BookCatalog
Get title data
Amazon
Get title data
LibraryOfCongress
Get title data
ChristianCatalog
Get title data
BookCopy
Main entry point
*
12. 12
copyright 2008 trainologic LTD
• Write a unit test for BookInventory.registerCopy
• A “good” copy can be registered
• Several copies can be registered for both same and
different titles
• A copy can only be registered if the title details are
known
• Same copy cannot be registered twice
• Same copy id for two different titles gives specific
error message
Exercise 1- BookInventory
12
Stubs
13. 13
copyright 2008 trainologic LTD
• Pros:
• We can write anything
• Cons:
• A lot of work
• Error prone
• Gets complicated as our demands increase:
• Was the catalog actually called?
• Was it called more than once?
• Was the isbn passed correctly to the catalog?
• What if two catalogs return different results?
Stubbing Pros and Cons
13
Stubs
15. 15
copyright 2008 trainologic LTD
• A Mock object is an object that:
• Is created by the mock framework
• Implements the same interface as the original
dependent object. Otherwise, the compiler won’t let
us pass it to the tested object.
• Supplies the tested code with everything it expects
from the dependent object.
• Allows us to check that the tested code is using the
dependent object (the Mock) correctly.
Mock Objects
15
Mocks
16. 16
copyright 2008 trainologic LTD
• To use a Mock object we should:
• Create instance of the Mock.
• Define bahavior during test.
• Invoke the tested code while passing the Mock as
parameter.
• Verify the Mock has been used correctly.
• Let’s see an example...
Introduction to Mock Objects
16
Mocks
17. 17
copyright 2008 trainologic LTD
17
Mocks
Example: Testing book addition
with Mock Title Catalog
Construct
Set behavior
Verify behavior
18. 18
copyright 2008 trainologic LTD
• Setup mocks for all dependencies required by our units
– Either as part of setUp (@Before) or at the beginning
of the test method
• Set mocks to correctly handle interaction – Usually at
the beginning of the test method
• Call business logic under testing
• Verify results & behavior (i.e. “side effects”)
The Typical Usage Pattern
18
Mocks
19. 19
copyright 2008 trainologic LTD
• When we set expectations on unit behavior, we are also
setting restrictions on how it is implemented
• It is very easy to create tests that are implementation
specific, and will break even though the unit is OK
• Such tests are called “brittle” and they are nightmare to
maintain
The danger of testing behavior
through mocks
19
Mocks
20. 20
copyright 2008 trainologic LTD
• Testing the SQL passed to the DB
• Verifying that the unit actually pulls data given by
mocks
• Testing for a specific order of calls to mocks
• Etc.
Some Examples of Brittle tests
20
Mocks
Over-Specified behavior == Brittle tests
22. 22
copyright 2008 trainologic LTD
Mockito
22
• An open-source project providing an easy way to work
with Mock objects.
• Can be freely downloaded from Google Code
http://code.google.com/p/mockito.
• Released under the MIT License.
Mockito
23. 23
copyright 2008 trainologic LTD
• No need to write Mock objects by hand.
• Simple “Set-Run-Verify” work model (as opposed to
(expect/record-run-verify)
• Refactoring-safe, no need to refactor Mock in case the
interface has changed.
• Supports return values and Exceptions.
• Flexible parameter handling in both set & verify
• Single jar, easy setup
• Easy to learn
Mockito - Benefits
23
Mockito
24. 24
copyright 2008 trainologic LTD
• Import Mockito – preferably static:
import static org.mockito.Mockito.*;
•Option 1: “mock” instead of “new”
IAccount mockAct= mock(IAccount.class);// or even…
Account mockAct= mock(Account.class); //on a concrete class
•Option 2: @mock a member
@mock private Account mockAct;
(But then you need to use MockitoAnnotations.initMocks or
JUnitMockitoRunner)
Constructing Mocks
24
Mockito
26. 26
copyright 2008 trainologic LTD
• Verify a function was called:
verify(mockedList).clear();
•Verify parameters passed:
verify(mockedList).add("one");
verify(mockedList).add(anyString());
•Verify number of invocations:
verify(mockedList,atLeastOnce()).add("one");
verify(mockedList,times(3)).add(anyString());
similarly: never, atLeast, atMost
•CAUTION: This is the heart of brittle testing!
Verifying Behavior
26
Mockito
27. 27
copyright 2008 trainologic LTD
• Using Mockito:
• Rewrite the tests from Exercise 1
• Also test that:
• BookInventory.registerCopy:
• Works well with several TitleCatalog objects
• Stops searching for book details once it has
them
• Extend BookInventory to support TitleCatalogs of
banned books. Test it.
(A copy of a banned book cannot be registered)
Exercise 2
27
Mockito
28. 28
copyright 2008 trainologic LTD
• Spy allows us to wrap a real object, and perform partial
mocking
• This is dangerous,
but may be relevant
with some legacy
code.
Partial Mocking: Spy Objects
28
Mockito
29. 29
copyright 2008 trainologic LTD
• Mockito allows you to verify the order in which methods
on mocks were called.
• This is yet another example of how you can create
extremely brittle tests. Use with caution.
Verifying call order
29
Mockito
30. 30
copyright 2008 trainologic LTD
• You can make sure a mock was not used through
verifyZeroInteractions
•You can make sure a mock was not used following
a specific verify through
verifyNoMoreInteractions
•Both are often over specification…
Expecting Nothing is Expecting Something
30
Mockito
32. copyright 2009 Trainologic LTD
• PowerMock is a framework that extends
Mockito/EasyMock. For Mockito it is called
PowerMockito.
• PowerMock uses a custom classloader and bytecode
manipulation to enable mocking of static
methods, constructors, final classes and
methods, private methods, and more.
• This is a mixed blessing:
• We can avoid re-factoring legacy code in order to
test it
• We are less inclined to fix bad design
PowerMock
EasyMock
33. copyright 2009 Trainologic LTD
• Lets see an example:
• We have the following class:
PowerMockito Example
EasyMock
35. 35
copyright 2008 trainologic LTD
EasyMock
• In order to unit-test isolated units we must use Mock
objects.
• Writing Mocks by hand is cumbersome.
• Mockito is a simple and easy to use library that helps us
create Mock implementations on the fly.
How do you know if a person really does unit testing?
Ask him what mocking framework he is using!
Summary
35