Download presentation
Presentation is loading. Please wait.
Published byAubrey Harper Modified over 8 years ago
1
Mock Objects in the Smalltalk World Dennis Schetinin
2
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
3
Do we need Mocks at all (in Smalltalk)? Why Mock Objects? 2 Mock Objects and Smalltalk
4
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?
5
…seems to be about testing Public Opinion 4
6
“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?
7
Cut off dependencies in tests Test-Driven Decomposition Discover Responsibility (for collaborators) Thinking vs. Speculating/Fantasizing Seamless TDD Why Mock Objects? 6
8
Dependencies How to cut them off? Novel Collaborators Where to cut? What Is The Problem? 7 Seamless TDD
9
Dependencies How to cut them off? Novel Collaborators Where to cut? What Is The problem? 8 Seamless TDD
10
We have: System Under Development (SUD) Collaborators Collaborators’ collaborators … Complex Test Dependencies 9 Seamless TDD — What’s the Problem?
11
We have to implement collaborators … without tests … loosing focus on SUD Digression So What? 10 Seamless TDD — Dependencies
12
Mocks Aren’t Stubs by Martin Fowler Filling orders from warehouse Dependencies: Example 11 Seamless TDD — Dependencies
13
OrderTests >> testIsFilledIfEnoughInWarehouse testIsFilledIfEnoughInWarehouse | order | order:= Order on: 50 of: #product. order fillFrom: warehouse. self assert: order isFilled Filling Order 12 Seamless TDD — Dependencies
14
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
15
I develop Order I don’t want to think about Warehouse Digression Detected! 14 Seamless TDD — Dependencies
16
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
17
Reduce amount of #product at the warehouse test…… self assert: (warehouse (warehouse amountOf: #product) amountOf: #product) isZero isZero …And Even More Digression 16 Seamless TDD — Dependencies
18
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
19
More complex test cases Collaborators’ logic becomes more and more complex… This can engulf … Much More Digression 18 Seamless TDD — Dependencies
20
SUD is Order Warehouse blures SUD #add:of: #amountOf: No explicit tests for Warehouse Not-So-Seamless TDD 19 Seamless TDD — Dependencies
21
OrderTests >> testIsFilledIfEnoughInWarehouse testIsFilledIfEnoughInWarehouse | order | | order | order := Order on: 50 of: #product. order := Order on: 50 of: #product. [ [ [ [ :warehouse| :warehouse| [order fillFrom: warehouse] [order fillFrom: warehouse] should satisfy: should satisfy: [“expectations”] [“expectations”] ] runScenario. ] runScenario. self assert: order isFilled self assert: order isFilled Mocking Warehouse 20 Seamless TDD — Dependencies
22
…[:warehouse| [order fillFrom: warehouse] should satisfy: should satisfy: [(warehouse [(warehouse has: 50 of: #product) has: 50 of: #product) willReturn: true. willReturn: true. warehouse warehouse remove: 50 of: #product] remove: 50 of: #product] ] runScenario. … Mocking Warehouse 21 Seamless TDD — Dependencies
23
Mock Objects in Smalltalk World The Mocketry Framework 22 Mock Objects and Smalltalk
24
When you do this with SUD, expect that to happen with collaborators Collaborators are mocked Behavior Expectations 23 Mocketry
25
Do this Expect that Behavior Expectations 24 Mocketry ExerciseVerify Scenario
26
SomeTestCases >> testCase [testScenario ] runScenario Mocketry Scenario Pattern 25 Mocketry – Behavior Expectations
27
SomeTestCases >> testCase [[exercise] should strictly satisfy: [behaviorExpectations] ] runScenario Mocketry Scenario Pattern 26 Mocketry – Behavior Expectations
28
Just send mock objects the messages they should receive warehouse has: 50 of: #product has: 50 of: #product Specify their reaction (warehouse has: 50 of: #product) has: 50 of: #product) willReturn: true willReturn: true Behavior Expectations 27 Mocketry — Behavior Expectations
29
SomeTestCases >> testCase [ [exercise] should strictly satisfy: [behaviorExpectations] … do anything ] runScenario Mocketry Scenario Pattern 28 Mocketry – Behavior Expectations
30
SomeTestCases >> testCase [ : mock | [exercise] should strictly satisfy: [behaviorExpectations] … do anything ] runScenario Mocketry Scenario Pattern 29 Mocketry – Behavior Expectations
31
SomeTestCases >> testCase [ :mock | [exercise] should strictly satisfy: [behaviorExpectations] … do anything ] runScenario Mocketry Scenario Pattern 30 Mocketry – Behavior Expectations
32
SomeTestCases >> testCase [ :mock1 :mock2 :mock3 | [exercise] should strictly satisfy: [behaviorExpectations] … do anything ] runScenario Mocketry Scenario Pattern 31 Mocketry – Behavior Expectations
33
TrueTests >> testDoesNotExecuteIfFalseBlock [ :block | [true ifFalse: block ] should satisfiy: [“nothing expected”] ] runScenario Trivial Example 1 32 Mocketry – Behavior Expectations
34
TrueTests >> testExecutesIfTrueBlock [ :block | [true ifTrue: block] should satisfiy: [block value] ] runScenario Trivial Example 2 33 Mocketry – Behavior Expectations
35
resultObject should resultObject should result should be: anotherObject result should equal: anotherObject ………… State Specification DSL 34 Mocketry
36
There is much more… Ask me …or Dennis Kudryashov (the Author) Mocketry 35
37
OrderTests >> testIsFilledIfEnoughInWarehouse | order | order := Order on: 50 of: #product. [:warehouse| [order fillFrom: warehouse] [order fillFrom: warehouse] should satisfy: should satisfy: [(warehouse has: 50 of: #product) [(warehouse has: 50 of: #product) willReturn: true. willReturn: true. warehouse remove: 50 of: #product] warehouse remove: 50 of: #product] ] runScenario. self assert: order isFilled Mocking Warehouse 36 Seamless TDD — Dependencies — Example
38
OrderTests >> testIsNotFilledIfNotEnoughInWarehouse | order | order := Order on: #amount of: #product. [:warehouse| [order fillFrom: warehouse] [order fillFrom: warehouse] should satisfy: should satisfy: [(warehouse has: 50 of: #product) [(warehouse has: 50 of: #product) willReturn: false. willReturn: false. “Nothing else is expected” ] “Nothing else is expected” ] ] runScenario. self assert: order isFilled Mocking Warehouse 37 Seamless TDD — Dependencies
39
No need to implement Warehouse Just specify expectations … right in the test Focus on the SUD What We Get 38 Why Mock Objects
40
Dependencies Novel Сollaborators What’s the problem? 39 Seamless TDD
41
Where to Start? 40 Seamless TDD — Novel Collaborators A novel system to implement Object 1 Object 2 Object 3 Object N …
42
Where to Cut? 41 Seamless TDD — Novel Collaborators A novel system to implement Feature
43
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
44
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
45
Scenario: User creates a game object User starts the game Game should generate a key ………… Bulls and Cows Game 44 Seamless TDD — Novel Collaborators
46
self assert: key …? self assert: key …? “How to represent key?!” “How to represent key?!” testGeneratesKeyOnStart 45 Seamless TDD — Novel Collaborators
47
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
48
… Create a new class for key Unnecessary complexity? What Can I Do? 47 Seamless TDD — Novel Collaborators
49
That was a Digression ! What Can I Do? 48 Seamless TDD — Novel Collaborators
50
|key| game start. key := game key. self assert: key isKindOf: Code testGeneratesKeyOnStart 49 Seamless TDD — Novel Collaborators
51
[ :keyGen | game keyGenerator: keyGen. game keyGenerator: keyGen. [ game start ] [ game start ] should satisfy: should satisfy: [keyGen createKey [keyGen createKey willReturn: #key] willReturn: #key] game key should be: #key game key should be: #key ] runScenario. testGeneratesKeyOnStart 50 Seamless TDD — Novel Collaborators
52
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
53
Seamless TDD: No digression No up-front decomposition No up-front design No speculating / fantasizing What We Get 52 Seamless TDD — Novel Collaborators
54
Mock Objects For Top-Down Design by Bulls-and-Cows Example Just ask! Complete Example 53
55
State vs. Behavior? Result vs. Intention? No contradiction! Mockist approach complements “classic” TDD Classic vs. Mockist TDD 54 Seamless TDD
56
Top-Down with Mockist TDD Analysis and Decomposition Bottom-Up with Classic TDD Synthesis and “real-object” testing Classic and Mockist TDD 55
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.