Overview§  Why Mock Objects?    §  “Mockist” vs. “Classic” TDD    §  “Mockist” and “Classic” TDD§  Mocks and Smalltalk...
Why Mock Objects?                 Do we need Mocks at all                          (in Smalltalk)?Mock Objects and Smallta...
Public Opinion§    Smalltalk vs. Mock Objects?      §  Few/rare special cases      §  With mock you don’t test real thi...
Public Opinion…seems to be about testing                             4
Smalltalk and Mock Objects§    “Mock Objects” is a TDD technique      §  … about developing systems      §  … not just ...
Why Mock Objects?§  Cut off dependencies in tests§  Test-Driven Decomposition      §  Discover Responsibility (for coll...
What Is The Problem?§    Dependencies      §    How to cut them off?§    Novel Collaborators      §    Where to cut?Se...
What Is The problem?§    Dependencies      §    How to cut them off?§    Novel Collaborators      §    Where to cut?Se...
DependenciesWe have:§  System Under Development (SUD)§  Collaborators§  Collaborators’ collaborators …             Comp...
So What?We have to implement collaborators§  … without tests§  … loosing focus on SUD              DigressionSeamless TD...
Dependencies: Example§    Mocks Aren’t Stubs by Martin Fowler§    Filling orders from warehouseSeamless TDD — Dependenci...
Filling OrderOrderTests >>    !  testIsFilledIfEnoughInWarehouse!!| order |!order:= Order on: 50 of: #product.!order fillF...
Filling OrderOrderTests >> !testIsFilledIfEnoughInWarehouse!| order warehouse |!!warehouse := Warehouse new.!“Put #product...
Digression Detected!§  I develop Order§  I don’t want to think about    WarehouseSeamless TDD — Dependencies       14
Filling OrderOrderTests >> !testIsFilledIfEnoughInWarehouse!| order warehouse |!warehouse := Warehouse new.!warehouse add:...
…And Even More DigressionReduce amount of #product at thewarehousetest…!…!self assert: !  (warehouse !    amountOf: #produ...
… And Even More DigressionAnother test case:If there isn’t enough #product in thewarehouse,§    do not fill order§    do...
… Much More Digression       More complex test cases Collaborators’ logic becomes more       and more complex…           T...
Not-So-Seamless TDD§  SUD is Order§  Warehouse blures SUD      §  #add:of:      §  #amountOf:§    No explicit tests f...
Mocking WarehouseOrderTests >> !  testIsFilledIfEnoughInWarehouse!   | order |!     order := Order on: 50 of: #product.!  ...
Mocking Warehouse…![:warehouse| ![order fillFrom: warehouse]!  should satisfy:!     [(warehouse !         has: 50 of: #pro...
The Mocketry    Framework                             Mock Objects in                             Smalltalk WorldMock Obje...
Behavior ExpectationsWhen you do this with SUD,  expect that to happen      with collaboratorsCollaborators are mockedMock...
Behavior Expectations    Do this      Exercise Expect that       Verify                  ScenarioMocketry                 ...
Mocketry Scenario PatternSomeTestCases >> testCase[     testScenario] runScenarioMocketry – Behavior Expectations   25
Mocketry Scenario PatternSomeTestCases >> testCase[     [exercise]         should strictly satisfy:             [behaviorE...
Behavior Expectations Just send mock objects the messages§ ! they should receivewarehouse !   has: 50 of: #product! Speci...
Mocketry Scenario PatternSomeTestCases >> testCase[     [exercise] should strictly satisfy: [behaviorExpectations]     [ex...
Mocketry Scenario PatternSomeTestCases >> testCase[ :mock |     [exercise] should strictly satisfy: [behaviorExpectations]...
Mocketry Scenario PatternSomeTestCases >> testCase[ :mock |     [exercise] should strictly satisfy: [behaviorExpectations]...
Mocketry Scenario PatternSomeTestCases >> testCase[ :mock1 :mock2 :mock3 |     [exercise] should strictly satisfy: [behavi...
Trivial Example 1TrueTests >>     testDoesNotExecuteIfFalseBlock[ :block |     [true ifFalse: block ]          should sati...
Trivial Example 2TrueTests >>     testExecutesIfTrueBlock[ :block |     [true ifTrue: block]          should satisfiy:    ...
State Specification DSL§    resultObject should <expectation>      §  result should be: anotherObject      §  result sh...
Mocketry§  There is much more…§  Ask me§  …or Dennis Kudryashov (the    Author)                                 35
Mocking WarehouseOrderTests >> !testIsFilledIfEnoughInWarehouse!| order |!order := Order on: 50 of: #product.!![:warehouse...
Mocking WarehouseOrderTests >> !testIsNotFilledIfNotEnoughInWarehouse!| order |!order := Order on: #amount of: #product.![...
What We Get§  No need to implement Warehouse§  Just specify expectations§  … right in the test§    Focus on the SUDWhy...
What’s the problem?§  Dependencies§  Novel СollaboratorsSeamless TDD              39
Where to Start?         A novel system to implement                 Object 2   Object 1                     Object N      ...
Where to Cut?         A novel system to implement                          Feature       Feature Feature Feature      Feat...
Where to Start?§    Try to guess      §  … and be ready to abandon test(s)      §  … or get a mess                   Or...
Novel Collaborators: ExampleBulls and Cows Game§  Computer generates a secret key      §    e.g., a 4-digit number§    ...
Bulls and Cows GameScenario:§  User creates a game object§  User starts the game      §    Game should generate a key§...
testGeneratesKeyOnStart!!    self assert: key …?!    “How to represent key?!”!Seamless TDD — Novel Collaborators   45
What Can I Do?§    Spontaneous representation      §    Do you feel lucky?§    Analyze thoroughly      §    Give up TD...
What Can I Do?§  …§  Create a new class for key      §    Unnecessary complexity?Seamless TDD — Novel Collaborators    47
What Can I Do?       That was a Digression!Seamless TDD — Novel Collaborators   48
testGeneratesKeyOnStart|key|!game start.!key := game key.!self assert: !  !key isKindOf: Code!Seamless TDD — Novel Collabo...
testGeneratesKeyOnStart[ :keyGen |! game keyGenerator: keyGen.! [ game start ]!   should satisfy:!     [keyGen createKey! ...
What We Get§    Key generation functionality      §  is revealed      §  moved to another object§    Dependency Inject...
What We GetSeamless TDD:§  No digression§  No up-front decomposition§  No up-front design§  No speculating / fantasizi...
Complete ExampleMock Objects For Top-Down Designby Bulls-and-Cows Example            Just ask!                            ...
Classic vs. Mockist TDD         State vs. Behavior?         Result vs. Intention?           No contradiction!       Mockis...
Classic and Mockist TDD§    Top-Down with Mockist TDD      §    Analysis and Decomposition§    Bottom-Up with Classic T...
Upcoming SlideShare
Loading in …5
×

Mock Objects and Smalltalk

1,497 views

Published on

ESUG 2011, Edinburgh

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,497
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
8
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Mock Objects and Smalltalk

  1. 1. Overview§  Why Mock Objects? §  “Mockist” vs. “Classic” TDD §  “Mockist” and “Classic” TDD§  Mocks and Smalltalk: §  The Mocketry framework introduction§  ExamplesMock Objects and Smalltalk 1
  2. 2. Why Mock Objects? Do we need Mocks at all (in Smalltalk)?Mock Objects and Smalltalk 2
  3. 3. Public Opinion§  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 meansDo we need Mock Objects at all? 3
  4. 4. Public Opinion…seems to be about testing 4
  5. 5. Smalltalk and Mock Objects§  “Mock Objects” is a TDD technique §  … about developing systems §  … not just testing §  … useful in all languages§  Smalltalk makes mocks §  much easier to useWhy Mock Objects? 5
  6. 6. Why Mock Objects?§  Cut off dependencies in tests§  Test-Driven Decomposition §  Discover Responsibility (for collaborators) §  Thinking vs. Speculating/Fantasizing Seamless TDDWhy Mock Objects? 6
  7. 7. What Is The Problem?§  Dependencies §  How to cut them off?§  Novel Collaborators §  Where to cut?Seamless TDD 7
  8. 8. What Is The problem?§  Dependencies §  How to cut them off?§  Novel Collaborators §  Where to cut?Seamless TDD 8
  9. 9. DependenciesWe have:§  System Under Development (SUD)§  Collaborators§  Collaborators’ collaborators … Complex TestSeamless TDD — What’s the Problem? 9
  10. 10. So What?We have to implement collaborators§  … without tests§  … loosing focus on SUD DigressionSeamless TDD — Dependencies 10
  11. 11. Dependencies: Example§  Mocks Aren’t Stubs by Martin Fowler§  Filling orders from warehouseSeamless TDD — Dependencies 11
  12. 12. Filling OrderOrderTests >> ! testIsFilledIfEnoughInWarehouse!!| order |!order:= Order on: 50 of: #product.!order fillFrom: warehouse.!self assert: order isFilled!Seamless TDD — Dependencies 12
  13. 13. Filling OrderOrderTests >> !testIsFilledIfEnoughInWarehouse!| order warehouse |!!warehouse := Warehouse new.!“Put #product there” !“…but how?!” !!order := Order on: 50 of: #product.!order fillFrom: warehouse.! …!Seamless TDD — Dependencies 13
  14. 14. Digression Detected!§  I develop Order§  I don’t want to think about WarehouseSeamless TDD — Dependencies 14
  15. 15. Filling OrderOrderTests >> !testIsFilledIfEnoughInWarehouse!| order warehouse |!warehouse := Warehouse new.!warehouse add: 50 of: #product.!!order := Order on: 50 of: #prod.!order fillFrom: warehouse.!…!Seamless TDD — Dependencies 15
  16. 16. …And Even More DigressionReduce amount of #product at thewarehousetest…!…!self assert: ! (warehouse ! amountOf: #product)! isZero!Seamless TDD — Dependencies 16
  17. 17. … And Even More DigressionAnother test case:If there isn’t enough #product in thewarehouse,§  do not fill order§  do not remove #product from warehouseSeamless TDD — Dependencies 17
  18. 18. … Much More Digression More complex test cases Collaborators’ logic becomes more and more complex… This can engulfSeamless TDD — Dependencies 18
  19. 19. Not-So-Seamless TDD§  SUD is Order§  Warehouse blures SUD §  #add:of: §  #amountOf:§  No explicit tests for WarehouseSeamless TDD — Dependencies 19
  20. 20. Mocking WarehouseOrderTests >> ! testIsFilledIfEnoughInWarehouse! | order |! order := Order on: 50 of: #product.! [! :warehouse| ! [order fillFrom: warehouse]! should satisfy:! [“expectations”]! ] runScenario.! self assert: order isFilled !Seamless TDD — Dependencies 20
  21. 21. Mocking Warehouse…![:warehouse| ![order fillFrom: warehouse]! should satisfy:! [(warehouse ! has: 50 of: #product)! willReturn: true. ! warehouse ! remove: 50 of: #product]!] runScenario.!…!Seamless TDD — Dependencies 21
  22. 22. The Mocketry Framework Mock Objects in Smalltalk WorldMock Objects and Smalltalk 22
  23. 23. Behavior ExpectationsWhen you do this with SUD, expect that to happen with collaboratorsCollaborators are mockedMocketry 23
  24. 24. Behavior Expectations Do this Exercise Expect that Verify ScenarioMocketry 24
  25. 25. Mocketry Scenario PatternSomeTestCases >> testCase[ testScenario] runScenarioMocketry – Behavior Expectations 25
  26. 26. Mocketry Scenario PatternSomeTestCases >> testCase[ [exercise] should strictly satisfy: [behaviorExpectations]] runScenarioMocketry – Behavior Expectations 26
  27. 27. Behavior Expectations Just send mock objects the messages§ ! they should receivewarehouse ! has: 50 of: #product! Specify their reaction§ (warehouse ! has: 50 of: #product) willReturn: trueMocketry — Behavior Expectations 27
  28. 28. Mocketry Scenario PatternSomeTestCases >> testCase[ [exercise] should strictly satisfy: [behaviorExpectations] [exercise] should strictly satisfy: [behaviorExpectations] … do anything] runScenarioMocketry – Behavior Expectations 28
  29. 29. Mocketry Scenario PatternSomeTestCases >> testCase[ :mock | [exercise] should strictly satisfy: [behaviorExpectations] [exercise] should strictly satisfy: [behaviorExpectations] … do anything] runScenarioMocketry – Behavior Expectations 29
  30. 30. Mocketry Scenario PatternSomeTestCases >> testCase[ :mock | [exercise] should strictly satisfy: [behaviorExpectations] [exercise] should strictly satisfy: [behaviorExpectations] … do anything] runScenarioMocketry – Behavior Expectations 30
  31. 31. Mocketry Scenario PatternSomeTestCases >> testCase[ :mock1 :mock2 :mock3 | [exercise] should strictly satisfy: [behaviorExpectations] [exercise] should strictly satisfy: [behaviorExpectations] … do anything] runScenarioMocketry – Behavior Expectations 31
  32. 32. Trivial Example 1TrueTests >> testDoesNotExecuteIfFalseBlock[ :block | [true ifFalse: block ] should satisfiy: [“nothing expected”]] runScenarioMocketry – Behavior Expectations 32
  33. 33. Trivial Example 2TrueTests >> testExecutesIfTrueBlock[ :block | [true ifTrue: block] should satisfiy: [block value]] runScenarioMocketry – Behavior Expectations 33
  34. 34. State Specification DSL§  resultObject should <expectation> §  result should be: anotherObject §  result should equal: anotherObject §  …Mocketry 34
  35. 35. Mocketry§  There is much more…§  Ask me§  …or Dennis Kudryashov (the Author) 35
  36. 36. Mocking WarehouseOrderTests >> !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 !Seamless TDD — Dependencies — Example 36
  37. 37. Mocking WarehouseOrderTests >> !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 !Seamless TDD — Dependencies 37
  38. 38. What We Get§  No need to implement Warehouse§  Just specify expectations§  … right in the test§  Focus on the SUDWhy Mock Objects 38
  39. 39. What’s the problem?§  Dependencies§  Novel СollaboratorsSeamless TDD 39
  40. 40. Where to Start? A novel system to implement Object 2 Object 1 Object N … Object 3Seamless TDD — Novel Collaborators 40
  41. 41. Where to Cut? A novel system to implement Feature Feature Feature Feature Feature Feature Feature Feature Feature FeatureFeatureSeamless TDD — Novel Collaborators 41
  42. 42. Where to Start?§  Try to guess §  … and be ready to abandon test(s) §  … or get a mess Or§  Analyze thoroughly §  … up-front decomposition §  … without tests — just a fantasySeamless TDD — Novel Collaborators 42
  43. 43. Novel Collaborators: ExampleBulls and Cows Game§  Computer generates a secret key §  e.g., a 4-digit number§  Human player tries to disclose itSeamless TDD — Novel Collaborators 43
  44. 44. Bulls and Cows GameScenario:§  User creates a game object§  User starts the game §  Game should generate a key§  …Seamless TDD — Novel Collaborators 44
  45. 45. testGeneratesKeyOnStart!! self assert: key …?! “How to represent key?!”!Seamless TDD — Novel Collaborators 45
  46. 46. What Can I Do?§  Spontaneous representation §  Do you feel lucky?§  Analyze thoroughly §  Give up TDD§  Postpone the test §  Not a solutionSeamless TDD — Novel Collaborators 46
  47. 47. What Can I Do?§  …§  Create a new class for key §  Unnecessary complexity?Seamless TDD — Novel Collaborators 47
  48. 48. What Can I Do? That was a Digression!Seamless TDD — Novel Collaborators 48
  49. 49. testGeneratesKeyOnStart|key|!game start.!key := game key.!self assert: ! !key isKindOf: Code!Seamless TDD — Novel Collaborators 49
  50. 50. testGeneratesKeyOnStart[ :keyGen |! game keyGenerator: keyGen.! [ game start ]! should satisfy:! [keyGen createKey! willReturn: #key]! game key should be: #key!] runScenario.!Seamless TDD — Novel Collaborators 50
  51. 51. What We Get§  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 decisionSeamless TDD — Novel Collaborators 51
  52. 52. What We GetSeamless TDD:§  No digression§  No up-front decomposition§  No up-front design§  No speculating / fantasizingSeamless TDD — Novel Collaborators 52
  53. 53. Complete ExampleMock Objects For Top-Down Designby Bulls-and-Cows Example Just ask! 53
  54. 54. Classic vs. Mockist TDD State vs. Behavior? Result vs. Intention? No contradiction! Mockist approach complements “classic” TDDSeamless TDD 54
  55. 55. Classic and Mockist TDD§  Top-Down with Mockist TDD §  Analysis and Decomposition§  Bottom-Up with Classic TDD §  Synthesis and “real-object” testing 55

×