mock objects and smalltalk

55
Why Mock Objects? “Mockist” vs. “Classic” TDD “Mockist” and Classic” TDD Mocks and Smalltalk: The Mocketry framework introduction Examples Overview 1 Mock Objects and Smalltalk

Upload: esug

Post on 10-May-2015

1.001 views

Category:

Technology


5 download

DESCRIPTION

ESUG 2011, Edinburgh

TRANSCRIPT

Page 1: Mock Objects and Smalltalk

§ Why Mock Objects? §  “Mockist” vs. “Classic” TDD §  “Mockist” and “Classic” TDD

§ Mocks and Smalltalk: §  The Mocketry framework introduction

§ Examples

Overview

1 Mock Objects and Smalltalk

Page 2: Mock Objects and Smalltalk

Do we need Mocks at all (in Smalltalk)?

Why Mock Objects?

2 Mock Objects and Smalltalk

Page 3: Mock Objects and Smalltalk

§ Smalltalk vs. Mock Objects? §  Few/rare special cases §  With mock you don’t test real thing §  Use mocks for external objects only §  Use other means to involve complex external objects

§  Speed up by other means

Public Opinion

3 Do we need Mock Objects at all?

Page 4: Mock Objects and Smalltalk

…seems to be about testing

Public Opinion

4

Page 5: Mock Objects and Smalltalk

§  “Mock Objects” is a TDD technique § … about developing systems § … not just testing § … useful in all languages

§ Smalltalk makes mocks §  much easier to use

Smalltalk and Mock Objects

5 Why Mock Objects?

Page 6: Mock Objects and Smalltalk

§ Cut off dependencies in tests §  Test-Driven Decomposition

§  Discover Responsibility (for collaborators) §  Thinking vs. Speculating/Fantasizing

Seamless TDD

Why Mock Objects?

6 Why Mock Objects?

Page 7: Mock Objects and Smalltalk

§ Dependencies §  How to cut them off?

§ Novel Collaborators §  Where to cut?

What Is The Problem?

7 Seamless TDD

Page 8: Mock Objects and Smalltalk

§ Dependencies §  How to cut them off?

§ Novel Collaborators §  Where to cut?

What Is The problem?

8 Seamless TDD

Page 9: Mock Objects and Smalltalk

We have: § System Under Development (SUD) § Collaborators § Collaborators’ collaborators …

Complex Test

Dependencies

9 Seamless TDD — What’s the Problem?

Page 10: Mock Objects and Smalltalk

We have to implement collaborators § … without tests § … loosing focus on SUD

Digression

So What?

10 Seamless TDD — Dependencies

Page 11: Mock Objects and Smalltalk

§  Mocks Aren’t Stubs by Martin Fowler

§ Filling orders from warehouse

Dependencies: Example

11 Seamless TDD — Dependencies

Page 12: Mock Objects and Smalltalk

OrderTests >> ! testIsFilledIfEnoughInWarehouse!!

| order |!order:= Order on: 50 of: #product.!order fillFrom: warehouse.!self assert: order isFilled!

Filling Order

12 Seamless TDD — Dependencies

Page 13: Mock Objects and Smalltalk

OrderTests >> !testIsFilledIfEnoughInWarehouse!| order warehouse |!

!warehouse := Warehouse new.!“Put #product there” !“…but how?!” !!

order := Order on: 50 of: #product.!order fillFrom: warehouse.! …!

Filling Order

13 Seamless TDD — Dependencies

Page 14: Mock Objects and Smalltalk

§  I develop Order §  I don’t want to think about Warehouse

Digression Detected!

14 Seamless TDD — Dependencies

Page 15: Mock Objects and Smalltalk

OrderTests >> !testIsFilledIfEnoughInWarehouse!| order warehouse |!

warehouse := Warehouse new.!warehouse add: 50 of: #product.!!

order := Order on: 50 of: #prod.!order fillFrom: warehouse.!…!

Filling Order

15 Seamless TDD — Dependencies

Page 16: Mock Objects and Smalltalk

Reduce amount of #product at the warehouse

test…!…!

self assert: ! (warehouse ! amountOf: #product)! isZero!

…And Even More Digression

16 Seamless TDD — Dependencies

Page 17: Mock Objects and Smalltalk

Another test case:

If there isn’t enough #product in the warehouse,

§ do not fill order

§ do not remove #product from warehouse

… And Even More Digression

17 Seamless TDD — Dependencies

Page 18: Mock Objects and Smalltalk

More complex test cases

Collaborators’ logic becomes more and more complex…

This can engulf

… Much More Digression

18 Seamless TDD — Dependencies

Page 19: Mock Objects and Smalltalk

§ SUD is Order § Warehouse blures SUD

§  #add:of: §  #amountOf:

§ No explicit tests for Warehouse

Not-So-Seamless TDD

19 Seamless TDD — Dependencies

Page 20: Mock Objects and Smalltalk

OrderTests >> ! testIsFilledIfEnoughInWarehouse!

| order |! order := Order on: 50 of: #product.! [! :warehouse| ! [order fillFrom: warehouse]! should satisfy:! [“expectations”]! ] runScenario.! self assert: order isFilled !

Mocking Warehouse

20 Seamless TDD — Dependencies

Page 21: Mock Objects and Smalltalk

…![:warehouse| ![order fillFrom: warehouse]! should satisfy:!

[(warehouse ! has: 50 of: #product)! willReturn: true. ! warehouse ! remove: 50 of: #product]!] runScenario.!

…!

Mocking Warehouse

21 Seamless TDD — Dependencies

Page 22: Mock Objects and Smalltalk

Mock Objects in Smalltalk World

The Mocketry Framework

22 Mock Objects and Smalltalk

Page 23: Mock Objects and Smalltalk

When you do this with SUD,

expect that to happen with collaborators

Collaborators are mocked

Behavior Expectations

23 Mocketry

Page 24: Mock Objects and Smalltalk

Do this

Expect that

Behavior Expectations

24 Mocketry

Exercise Verify

Scenario

Page 25: Mock Objects and Smalltalk

SomeTestCases >> testCase [

testScenario ] runScenario

Mocketry Scenario Pattern

25 Mocketry – Behavior Expectations

Page 26: Mock Objects and Smalltalk

SomeTestCases >> testCase [

[exercise] should strictly satisfy: [behaviorExpectations]

] runScenario

Mocketry Scenario Pattern

26 Mocketry – Behavior Expectations

Page 27: Mock Objects and Smalltalk

§  Just send mock objects the messages they should receive

!

warehouse ! has: 50 of: #product!

§  Specify their reaction

(warehouse ! has: 50 of: #product) willReturn: true

Behavior Expectations

27 Mocketry — Behavior Expectations

Page 28: Mock Objects and Smalltalk

SomeTestCases >> testCase [

[exercise] should strictly satisfy: [behaviorExpectations]

[exercise] should strictly satisfy: [behaviorExpectations]

… do anything ] runScenario

Mocketry Scenario Pattern

28 Mocketry – Behavior Expectations

Page 29: Mock Objects and Smalltalk

SomeTestCases >> testCase

[ :mock | [exercise] should strictly satisfy: [behaviorExpectations]

[exercise] should strictly satisfy: [behaviorExpectations]

… do anything

] runScenario

Mocketry Scenario Pattern

29 Mocketry – Behavior Expectations

Page 30: Mock Objects and Smalltalk

SomeTestCases >> testCase

[ :mock | [exercise] should strictly satisfy: [behaviorExpectations]

[exercise] should strictly satisfy: [behaviorExpectations]

… do anything ] runScenario

Mocketry Scenario Pattern

30 Mocketry – Behavior Expectations

Page 31: Mock Objects and Smalltalk

SomeTestCases >> testCase [ :mock1 :mock2 :mock3 |

[exercise] should strictly satisfy: [behaviorExpectations]

[exercise] should strictly satisfy: [behaviorExpectations]

… do anything ] runScenario

Mocketry Scenario Pattern

31 Mocketry – Behavior Expectations

Page 32: Mock Objects and Smalltalk

TrueTests >> testDoesNotExecuteIfFalseBlock

[ :block | [true ifFalse: block ] should satisfiy: [“nothing expected”]

] runScenario

Trivial Example 1

32 Mocketry – Behavior Expectations

Page 33: Mock Objects and Smalltalk

TrueTests >> testExecutesIfTrueBlock

[ :block | [true ifTrue: block] should satisfiy: [block value]

] runScenario

Trivial Example 2

33 Mocketry – Behavior Expectations

Page 34: Mock Objects and Smalltalk

§  resultObject should <expectation> §  result should be: anotherObject §  result should equal: anotherObject § …

State Specification DSL

34 Mocketry

Page 35: Mock Objects and Smalltalk

§ There is much more… § Ask me § …or Dennis Kudryashov (the Author)

Mocketry

35

Page 36: Mock Objects and Smalltalk

OrderTests >> !testIsFilledIfEnoughInWarehouse!| order |!order := Order on: 50 of: #product.!!

[:warehouse| ! [order fillFrom: warehouse]! should satisfy:! [(warehouse has: 50 of: #product)! willReturn: true. ! warehouse remove: 50 of: #product]!] runScenario.!!

self assert: order isFilled !

Mocking Warehouse

36 Seamless TDD — Dependencies — Example

Page 37: Mock Objects and Smalltalk

OrderTests >> !testIsNotFilledIfNotEnoughInWarehouse!| order |!order := Order on: #amount of: #product.![:warehouse| ! [order fillFrom: warehouse]! should satisfy:! [(warehouse has: 50 of: #product)! willReturn: false. ! “Nothing else is expected” ]!] runScenario.!self assert: order isFilled !

Mocking Warehouse

37 Seamless TDD — Dependencies

Page 38: Mock Objects and Smalltalk

§ No need to implement Warehouse § Just specify expectations § … right in the test

§ Focus on the SUD

What We Get

38 Why Mock Objects

Page 39: Mock Objects and Smalltalk

§ Dependencies § Novel Сollaborators

What’s the problem?

39 Seamless TDD

Page 40: Mock Objects and Smalltalk

Where to Start?

40 Seamless TDD — Novel Collaborators

A novel system to implement

Object 1

Object 2

Object 3

Object N …

Page 41: Mock Objects and Smalltalk

Where to Cut?

41 Seamless TDD — Novel Collaborators

A novel system to implement

Feature Feature Feature

Feature Feature

Feature Feature

Feature

Feature Feature

Feature

Page 42: Mock Objects and Smalltalk

§ Try to guess § … and be ready to abandon test(s) § … or get a mess

Or § Analyze thoroughly

§ … up-front decomposition § … without tests — just a fantasy

Where to Start?

42 Seamless TDD — Novel Collaborators

Page 43: Mock Objects and Smalltalk

Bulls and Cows Game § Computer generates a secret key

§  e.g., a 4-digit number § Human player tries to disclose it

Novel Collaborators: Example

43 Seamless TDD — Novel Collaborators

Page 44: Mock Objects and Smalltalk

Scenario: § User creates a game object § User starts the game

§  Game should generate a key § …

Bulls and Cows Game

44 Seamless TDD — Novel Collaborators

Page 45: Mock Objects and Smalltalk

!!

self assert: key …?! “How to represent key?!”!

testGeneratesKeyOnStart

45 Seamless TDD — Novel Collaborators

Page 46: Mock Objects and Smalltalk

§ Spontaneous representation §  Do you feel lucky?

§ Analyze thoroughly §  Give up TDD

§ Postpone the test §  Not a solution

What Can I Do?

46 Seamless TDD — Novel Collaborators

Page 47: Mock Objects and Smalltalk

§ … § Create a new class for key

§  Unnecessary complexity?

What Can I Do?

47 Seamless TDD — Novel Collaborators

Page 48: Mock Objects and Smalltalk

That was a Digression!

What Can I Do?

48 Seamless TDD — Novel Collaborators

Page 49: Mock Objects and Smalltalk

|key|!game start.!key := game key.!self assert: !!key isKindOf: Code!

testGeneratesKeyOnStart

49 Seamless TDD — Novel Collaborators

Page 50: Mock Objects and Smalltalk

[ :keyGen |! game keyGenerator: keyGen.! [ game start ]! should satisfy:! [keyGen createKey! willReturn: #key]! game key should be: #key!] runScenario.!

testGeneratesKeyOnStart

50 Seamless TDD — Novel Collaborators

Page 51: Mock Objects and Smalltalk

§ Key generation functionality §  is revealed §  moved to another object

§ Dependency Injection §  fake key can be created for tests §  KeyGenerator refactored to Turn

§ No risk of incorrect decision

What We Get

51 Seamless TDD — Novel Collaborators

Page 52: Mock Objects and Smalltalk

Seamless TDD: § No digression § No up-front decomposition § No up-front design § No speculating / fantasizing

What We Get

52 Seamless TDD — Novel Collaborators

Page 53: Mock Objects and Smalltalk

Mock Objects For Top-Down Design by Bulls-and-Cows Example

Just ask!

Complete Example

53

Page 54: Mock Objects and Smalltalk

State vs. Behavior? Result vs. Intention?

No contradiction!

Mockist approach complements “classic” TDD

Classic vs. Mockist TDD

54 Seamless TDD

Page 55: Mock Objects and Smalltalk

§ Top-Down with Mockist TDD §  Analysis and Decomposition

§ Bottom-Up with Classic TDD §  Synthesis and “real-object” testing

Classic and Mockist TDD

55