tdd - test doubles
DESCRIPTION
Slides for a little introduction to test doubles given at the madrid software craftsmanship group.TRANSCRIPT
Test Doubles @AlfredoCasado
Object oriented system
storage
messaging
Object oriented system
storage
messaging
Object oriented system
storage
messaging
Object oriented system
storage
messaging
Object oriented system
storage
messaging
Object oriented system
storage
messaging
Problem: test only a selected subset of elements
storage
messaging
Solution: use test doubles to isolate
STUBS● Use stubs to simulate inputs to your system
under test.● In BDD terminology, stubs helps in the given
part of the test.
Example: calculating a student's grade point average
averageGrade(student)stub
grades(student)
OOP: 8,Algorithms: 6,FP: 6,Databases: 10
7,5
Code example (groovy with spock)
def "calculate average grade"() { given: def stub = Mock(GradesRepository) { grades('alfredo') >> [OOP: 8,algorithms: 6,FP: 6,databases: 10] }
def gradesEvaluator = new GradesEvaluator(gradesRepository: stub)
expect: gradesEvaluator.averageGrade('alfredo') == 7.5
}
stub creation
Code example (groovy with spock)
def "calculate average grade"() { given: def stub = Mock(GradesRepository) { grades('alfredo') >> [OOP: 8,algorithms: 6,FP: 6,databases: 10] }
def gradesEvaluator = new GradesEvaluator(gradesRepository: stub)
expect: gradesEvaluator.averageGrade('alfredo') == 7.5
}
stub injection
Mocks/Spies● Use mocks/Spies to verify outputs of your system under
test.● In BDD terminology, mocks/spies helps in the then part
of the test.● With mocks you set expectations before call the SUT,
this are usually “strict” expectations and no other interactions with the double are allowed.
● With spies you check the interactions with the double after call the SUT.
Example: Domotic system
activateSecurity()
WindowsMockclose()
close() DoorsMock
output you want to verify
Code example with mocks (java & jmock)
@Test public void test_activate_security() { final WindowController windowMock = context.mock(WindowController.class); final DoorsController doorsMock = context.mock(DoorsController.class); context.checking(new Expectations() {{ oneOf(windowMock).close(); oneOf(doorsMock).close(); }}); DomoticSystem domotic = new DomoticSystem(windowMock, doorsMock); domotic.activateSecurity(); context.assertIsSatisfied(); }
mocks creation
@Test public void test_activate_security() { final WindowController windowMock = context.mock(WindowController.class); final DoorsController doorsMock = context.mock(DoorsController.class); context.checking(new Expectations() {{ oneOf(windowMock).close(); oneOf(doorsMock).close(); }}); DomoticSystem domotic = new DomoticSystem(windowMock, doorsMock); domotic.activateSecurity(); context.assertIsSatisfied(); }
Code example with mocks (java & jmock)
set expectations
@Test public void test_activate_security() { final WindowController windowMock = context.mock(WindowController.class); final DoorsController doorsMock = context.mock(DoorsController.class); context.checking(new Expectations() {{ oneOf(windowMock).close(); oneOf(doorsMock).close(); }}); DomoticSystem domotic = new DomoticSystem(windowMock, doorsMock); domotic.activateSecurity(); context.assertIsSatisfied(); }
Code example with mocks (java & jmock)
verify interactions
@Test public void test_activate_security() { WindowController windowSpy = mock(WindowController.class); DoorsController doorsSpy = mock(DoorsController.class); DomoticSystem domotic = new DomoticSystem(windowSpy, doorsSpy); domotic.activateSecurity(); verify(windowSpy).close(); verify(doorsSpy).close(); }
Code example with spies (java & mockito)
spy creation
Code example with spies (java & mockito)
@Test public void test_activate_security() { WindowController windowSpy = mock(WindowController.class); DoorsController doorsSpy = mock(DoorsController.class); DomoticSystem domotic = new DomoticSystem(windowSpy, doorsSpy); domotic.activateSecurity(); verify(windowSpy).close(); verify(doorsSpy).close(); }
verify interactions
Recommendations● Test features not methods or classes● Kent Beck definition of unit test is a test that
can run in isolation from other test. A unit test is not test a class in isolation.
● Don’t use test doubles for Value Objects● Don’t use test doubles for types you don’t
own