mock objects in the smalltalk world

56
Mock Objects in the Smalltalk World Dennis Schetinin

Upload: crwys

Post on 23-Feb-2016

59 views

Category:

Documents


2 download

DESCRIPTION

Mock Objects in the Smalltalk World. Dennis Schetinin. Overview. Why Mock Objects? “Mockist” vs. “Classic” TDD “Mockist” and “ Classic” TDD Mocks and Smalltalk: The Mocketry framework i ntroduction Examples. Why Mock Objects?. Do we need Mocks at all (in Smalltalk)?. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Mock Objects in the Smalltalk World

Mock Objects in the Smalltalk World

Dennis Schetinin

Page 2: Mock Objects in the Smalltalk World

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

Mocks and Smalltalk: The Mocketry framework introduction

Examples

Overview

2Mock Objects and Smalltalk

Page 3: Mock Objects in the Smalltalk World

Mock Objects and Smalltalk

Do we need Mocks at all (in Smalltalk)?

Why Mock Objects?

3

Page 4: Mock Objects in the Smalltalk World

Do we need Mock Objects at all?

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

4

Page 5: Mock Objects in the Smalltalk World

…seems to be about testing

Public Opinion

5

Page 6: Mock Objects in the Smalltalk World

Why Mock Objects?

“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

6

Page 7: Mock Objects in the Smalltalk World

Cut off dependencies in tests Test-Driven Decomposition

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

Seamless TDD

Why Mock Objects?

7Why Mock Objects?

Page 8: Mock Objects in the Smalltalk World

Seamless TDD

Dependencies How to cut them off?

Novel Collaborators Where to cut?

What Is The Problem?

8

Page 9: Mock Objects in the Smalltalk World

Seamless TDD

Dependencies How to cut them off?

Novel Collaborators Where to cut?

What Is The problem?

9

Page 10: Mock Objects in the Smalltalk World

Seamless TDD — What’s the Problem?

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

Complex Test

Dependencies

10

Page 11: Mock Objects in the Smalltalk World

Seamless TDD — Dependencies

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

Digression

So What?

11

Page 12: Mock Objects in the Smalltalk World

Seamless TDD — Dependencies

Mocks Aren’t Stubs by Martin Fowler

Filling orders from warehouse

Dependencies: Example

12

Page 13: Mock Objects in the Smalltalk World

OrderTests >> testIsFilledIfEnoughInWarehouse

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

Filling Order

13Seamless TDD — Dependencies

Page 14: Mock Objects in the Smalltalk World

OrderTests >> testIsFilledIfEnoughInWarehouse| order warehouse |

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

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

Filling Order

14Seamless TDD — Dependencies

Page 15: Mock Objects in the Smalltalk World

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

Digression Detected!

15Seamless TDD — Dependencies

Page 16: Mock Objects in the Smalltalk World

OrderTests >> testIsFilledIfEnoughInWarehouse| order warehouse |

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

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

Filling Order

16Seamless TDD — Dependencies

Page 17: Mock Objects in the Smalltalk World

Reduce amount of #product at the warehousetest……

self assert: (warehouse amountOf: #product) isZero

…And Even More Digression

17Seamless TDD — Dependencies

Page 18: Mock Objects in the Smalltalk World

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

18Seamless TDD — Dependencies

Page 19: Mock Objects in the Smalltalk World

More complex test cases

Collaborators’ logic becomes more and more complex…

This can engulf

… Much More Digression

19Seamless TDD — Dependencies

Page 20: Mock Objects in the Smalltalk World

SUD is Order Warehouse blures SUD

#add:of: #amountOf:

No explicit tests for Warehouse

Not-So-Seamless TDD

20Seamless TDD — Dependencies

Page 21: Mock Objects in the Smalltalk World

OrderTests >> testIsFilledIfEnoughInWarehouse

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

Mocking Warehouse

21Seamless TDD — Dependencies

Page 22: Mock Objects in the Smalltalk World

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

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

Mocking Warehouse

22Seamless TDD — Dependencies

Page 23: Mock Objects in the Smalltalk World

Mock Objects and Smalltalk

Mock Objects in Smalltalk World

The Mocketry Framework

23

Page 24: Mock Objects in the Smalltalk World

Mocketry

When you do this with SUD,expect that to happen

with collaborators

Collaborators are mocked

Behavior Expectations

24

Page 25: Mock Objects in the Smalltalk World

Mocketry

Do this

Expect that

Behavior Expectations

25

Exercise

Verify

Scenario

Page 26: Mock Objects in the Smalltalk World

Mocketry – Behavior Expectations

SomeTestCases >> testCase[

testScenario

] runScenario

Mocketry Scenario Pattern

26

Page 27: Mock Objects in the Smalltalk World

Mocketry – Behavior Expectations

SomeTestCases >> testCase[

[exercise] should strictly satisfy:

[behaviorExpectations] ] runScenario

Mocketry Scenario Pattern

27

Page 28: Mock Objects in the Smalltalk World

Mocketry — Behavior Expectations

Just send mock objects the messages they should receivewarehouse has: 50 of: #product Specify their reaction(warehouse has: 50 of: #product) willReturn: true

Behavior Expectations

28

Page 29: Mock Objects in the Smalltalk World

Mocketry – Behavior Expectations

SomeTestCases >> testCase[ [exercise] should strictly satisfy: [behaviorExpectations]

[exercise] should strictly satisfy: [behaviorExpectations]

… do anything] runScenario

Mocketry Scenario Pattern

29

Page 30: Mock Objects in the Smalltalk World

Mocketry – Behavior Expectations

SomeTestCases >> testCase

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

[exercise] should strictly satisfy: [behaviorExpectations]

… do anything

] runScenario

Mocketry Scenario Pattern

30

Page 31: Mock Objects in the Smalltalk World

Mocketry – Behavior Expectations

SomeTestCases >> testCase

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

[exercise] should strictly satisfy: [behaviorExpectations]

… do anything] runScenario

Mocketry Scenario Pattern

31

Page 32: Mock Objects in the Smalltalk World

Mocketry – Behavior Expectations

SomeTestCases >> testCase[ :mock1 :mock2 :mock3 |[exercise] should strictly satisfy: [behaviorExpectations]

[exercise] should strictly satisfy: [behaviorExpectations]

… do anything] runScenario

Mocketry Scenario Pattern

32

Page 33: Mock Objects in the Smalltalk World

Mocketry – Behavior Expectations

TrueTests >>testDoesNotExecuteIfFalseBlock

[ :block |[true ifFalse: block ]

should satisfiy:[“nothing expected”]

] runScenario

Trivial Example 1

33

Page 34: Mock Objects in the Smalltalk World

Mocketry – Behavior Expectations

TrueTests >>testExecutesIfTrueBlock

[ :block |[true ifTrue: block]

should satisfiy: [block value]

] runScenario

Trivial Example 2

34

Page 35: Mock Objects in the Smalltalk World

Mocketry

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

State Specification DSL

35

Page 36: Mock Objects in the Smalltalk World

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

Mocketry

36

Page 37: Mock Objects in the Smalltalk World

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

37Seamless TDD — Dependencies — Example

Page 38: Mock Objects in the Smalltalk World

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

38Seamless TDD — Dependencies

Page 39: Mock Objects in the Smalltalk World

Why Mock Objects

No need to implement Warehouse Just specify expectations … right in the test Focus on the SUD

What We Get

39

Page 40: Mock Objects in the Smalltalk World

Seamless TDD

Dependencies Novel Сollaborators

What’s the problem?

40

Page 41: Mock Objects in the Smalltalk World

Seamless TDD — Novel Collaborators

Where to Start?

41

A novel system to implement

Object 1

Object 2

Object 3

Object N…

Page 42: Mock Objects in the Smalltalk World

Seamless TDD — Novel Collaborators

Where to Cut?

42

A novel system to implement

FeatureFeatureFeature

FeatureFeature

FeatureFeature

Feature

FeatureFeature

Feature

Page 43: Mock Objects in the Smalltalk World

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?

43Seamless TDD — Novel Collaborators

Page 44: Mock Objects in the Smalltalk World

Seamless TDD — Novel Collaborators

Bulls and Cows Game Computer generates a secret key

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

Novel Collaborators: Example

44

Page 45: Mock Objects in the Smalltalk World

Scenario: User creates a game object User starts the game

Game should generate a key …

Bulls and Cows Game

45Seamless TDD — Novel Collaborators

Page 46: Mock Objects in the Smalltalk World

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

testGeneratesKeyOnStart

46Seamless TDD — Novel Collaborators

Page 47: Mock Objects in the Smalltalk World

Seamless TDD — Novel Collaborators

Spontaneous representation Do you feel lucky?

Analyze thoroughly Give up TDD

Postpone the test Not a solution

What Can I Do?

47

Page 48: Mock Objects in the Smalltalk World

Seamless TDD — Novel Collaborators

… Create a new class for key

Unnecessary complexity?

What Can I Do?

48

Page 49: Mock Objects in the Smalltalk World

Seamless TDD — Novel Collaborators

That was a Digression!

What Can I Do?

49

Page 50: Mock Objects in the Smalltalk World

|key|game start.key := game key.self assert:

key isKindOf: Code

testGeneratesKeyOnStart

50Seamless TDD — Novel Collaborators

Page 51: Mock Objects in the Smalltalk World

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

testGeneratesKeyOnStart

51Seamless TDD — Novel Collaborators

Page 52: Mock Objects in the Smalltalk World

Seamless TDD — Novel Collaborators

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

52

Page 53: Mock Objects in the Smalltalk World

Seamless TDD — Novel Collaborators

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

What We Get

53

Page 54: Mock Objects in the Smalltalk World

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

Just ask!

Complete Example

54

Page 55: Mock Objects in the Smalltalk World

State vs. Behavior?Result vs. Intention?

No contradiction!

Mockist approach complements “classic” TDD

Classic vs. Mockist TDD

55Seamless TDD

Page 56: Mock Objects in the Smalltalk World

Top-Down with Mockist TDD Analysis and Decomposition

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

Classic and Mockist TDD

56