stop mocking and get real

41
© Zühlke 2014 Rick Janda, Immo Hüneke Less mocking, less brittle tests – BCS SPA 2014 Stop Mocking and Get Real 1. July 2014 Slide 1 of 41

Upload: immo-hueneke

Post on 08-Jul-2015

143 views

Category:

Technology


0 download

DESCRIPTION

Slide deck to accompany talk on ideas on test refactoring mainly developed by Rick Janda to help make unit tests less brittle and more readable. Delivered by Immo Huneke at the BCS SPA2014 conference in London (1 July 2014)

TRANSCRIPT

Page 1: Stop Mocking and Get Real

© Zühlke 2014

Rick Janda, Immo Hüneke

Less mocking, less brittle tests – BCS SPA 2014

Stop Mocking and Get Real

1. July 2014 Slide 1 of 41

Page 2: Stop Mocking and Get Real

© Zühlke 2014

Kai Zen

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 2 of 41

Page 3: Stop Mocking and Get Real
Page 4: Stop Mocking and Get Real
Page 5: Stop Mocking and Get Real
Page 6: Stop Mocking and Get Real

© Zühlke 2014

Stop Mocking and Get Real

Rick Janda, Immo Hüneke

What could be the problem with Mock Objects?

1. July 2014 Slide 6 of 41

Page 7: Stop Mocking and Get Real

© Zühlke 2014

• …test the "How" and not the "What" – Lead to fragile tests, thanks to multiple dependencies

• …mirror the code of the Unit under Test – Violate the D.R.Y. principle

• …test based on unvalidated assumptions – Foster a false sense of security

• … have complicated syntax to setup – Make tests hard to read

Mock Objects…

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 7 of 41

Page 8: Stop Mocking and Get Real

© Zühlke 2014

Tell, don't ask

• Some commentators recommend the "tell, don't ask" style of coding interactions to reduce the amount of distributed state

• Where a number of collaborators are needed to complete an interaction, each one typically returns some value that is used as input to the next

• This leads to a proliferation of mock objects

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 8 of 41

Page 9: Stop Mocking and Get Real

© Zühlke 2014

• Pain Killers – alleviate the symptoms

• Treatments – address the real causes of pain

Escape from Mocking Hell

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 9 of 41

Page 10: Stop Mocking and Get Real

© Zühlke 2014

Stop Mocking and Get Real

Rick Janda, Immo Hüneke

- 3 Pain Killers -

1. July 2014 Slide 10 of 41

Page 11: Stop Mocking and Get Real

© Zühlke 2014

Pain Killer I: Use Stubs instead of Mocks

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 11 of 41

Page 12: Stop Mocking and Get Real

© Zühlke 2014

What does the test need to assert?

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 12 of 41

Page 13: Stop Mocking and Get Real

© Zühlke 2014

Use mocks only where needed (e.g. to test collaboration or to inject return values)

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 13 of 41

Page 14: Stop Mocking and Get Real

© Zühlke 2014

Pain Killer II: Give Unit Tests a single responsibility.

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 14 of 41

Page 15: Stop Mocking and Get Real

© Zühlke 2014

What can a unit test assert?

• Return value

• State of the UUT (Unit Under Test)

• State of a collaborator

• Behaviour of the UUT against a collaborator

Choose which of these your test is designed to prove.

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 15 of 41

Page 16: Stop Mocking and Get Real

© Zühlke 2014

Pain Killer III: Hand-code test doubles or use library classes where possible

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 16 of 41

Page 17: Stop Mocking and Get Real

© Zühlke 2014

• ByteArrayInputStream and ByteArrayOutputStream for Streams – Make assertions about the toString() result – Allow changes in the how.

• CharArrayReader and CharArrayWriter for Reader/Writer – Very similar

• MockHttpSession, MockHttpServletRequest and MockHttpServletResponse for Servlet API interfaces – part of Spring Testing

Examples

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 17 of 41

Page 18: Stop Mocking and Get Real

© Zühlke 2014

Stop Mocking and Get Real

Rick Janda, Immo Hüneke

Treatments that address the causes of pain Why do we use Mocks or Stubs in Unit Tests?

1. July 2014 Slide 18 of 41

Page 19: Stop Mocking and Get Real

© Zühlke 2014

Collaborators can be placed on an “awkwardness scale”

Test Doubles as Substitute Collaborators

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 19 of 41

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

Simple and straightforward Hard Awkward Soft Awkward

Page 20: Stop Mocking and Get Real

© Zühlke 2014

• Slow

• Hard to create

• Hard to control

Typical of physical resources or runtime environment:

• I/O

• Network

• Timer

• Stochastic

• Container

• Process

Awkward Collaborators

1. July 2014 Slide 20 of 41

Page 21: Stop Mocking and Get Real

© Zühlke 2014

• Fast

• Easy to create

• Easy to setup

• Easy access to state

Typical of more intelligent data structures:

• Value Objects or Transfer Objects

• Entities

• Composite data structures (Mapped XML or JSON)

• also: Method objects

Simple Collaborators

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 21 of 41

Page 22: Stop Mocking and Get Real

© Zühlke 2014

Simple Rule

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 22 of 41

Page 23: Stop Mocking and Get Real

© Zühlke 2014

- Design Changes -

Reducing the need for mocks and stubs

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 23 of 41

Page 24: Stop Mocking and Get Real

© Zühlke 2014

Tackle the causes of awkwardness

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 24 of 41

Page 25: Stop Mocking and Get Real

© Zühlke 2014

Isolation combats infection

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 25 of 41

Page 26: Stop Mocking and Get Real

© Zühlke 2014

Separation of concerns – an analogy

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 26 of 41

Page 27: Stop Mocking and Get Real

© Zühlke 2014

Categorise objects by their role … refactoring where necessary

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 27 of 41

Page 28: Stop Mocking and Get Real

© Zühlke 2014

Refactoring for testability: Separate concerns by subdividing methods

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 28 of 41

Page 29: Stop Mocking and Get Real

© Zühlke 2014

Refactoring for testability: Separate concerns by redistributing code

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 29 of 41

Page 30: Stop Mocking and Get Real

© Zühlke 2014

Primary Constructor

• Eliminate need to inject an awkward collaborator by providing an alternative constructor just used in testing

Pull out query to awkward collaborator

• Make query result an argument to a simple testable method

Separate decision making from decision execution

• Create a testable decision making method that returns selector or argument values

• Use the result to invoke collaboration with awkward collaborator

Function below – objects above

• Organise functions under objects – simplify function arguments

Refactoring for testability: Move the logic to the leaves

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 30 of 41

Page 31: Stop Mocking and Get Real

© Zühlke 2014

Extract Awkwardness into Adapters

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 31 of 41

Page 32: Stop Mocking and Get Real

© Zühlke 2014

Build Rich Domain Objects

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 32 of 41

Page 33: Stop Mocking and Get Real

© Zühlke 2014

After Separation into Awkward / Simple

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 33 of 41

Page 34: Stop Mocking and Get Real

© Zühlke 2014

Architecture for Testability: Simple Core – Awkward Shell

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 34 of 41

Page 35: Stop Mocking and Get Real

© Zühlke 2014

Simple Core – Awkward Shell example

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 35 of 41

Page 36: Stop Mocking and Get Real

© Zühlke 2014

Architecture for Testability: Simple Boundary

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 36 of 41

Page 37: Stop Mocking and Get Real

© Zühlke 2014

Simple Boundary Example: Segregate the Awkward

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 37 of 41

Page 38: Stop Mocking and Get Real

© Zühlke 2014

Putting it All Together: Simple Core – Awkward Shell & Simple Boundary

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 38 of 41

Page 39: Stop Mocking and Get Real

© Zühlke 2014

Your Tests Require Lots of Stubbing and Mocking?

Change Your Design

Towards Better Testability!

Stop Mocking and Get Real | Rick Janda, Immo Hüneke 1. July 2014 Slide 39 of 41

Page 40: Stop Mocking and Get Real

© Zühlke 2014

Change Your Design for Better Testability

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 40 of 41

Page 41: Stop Mocking and Get Real

© Zühlke 2014

Remember…

1. July 2014 Stop Mocking and Get Real | Rick Janda, Immo Hüneke Slide 41 of 41