Mocking in Python

Post on 15-Jul-2015

290 views 0 download

Tags:

transcript

Mocking Strategies

Please don’t mock me after this

presentation…

Daniel Davis

• Daniel Davis

• Software Developer for 8 years

• Fun Fact:

– I ran the “Jingle All The Way” 5k dressed as a

Giant Gingerbread man

Who Am I?

3

Really though, who are you?

• Came from Java world

• Python developer for 2 years

• DevOps

– Lots of work with automation and quality

• Passionate about quality!

– Doesn’t happen overnight…

Testing Journey

• Became a Certified Scrum Developer

(CSD) about 2 years ago

• Finally learned about craftsmanship and

writing better tests

– Basically black magic

• Learned in Java…

I want to be a better developer

• Switching to Python was jarring

• Kept wondering about writing unit tests

• Dealing with complicated frameworks like

Django

Finding Python

7

• Asked colleagues

– Many had the same questions

• Decided to learn…

• Wanted to share with the community

Unit testing? Mocks?

8

Let’s Talk About Unit Tests…

Unit – 70%

Integration

– 20%

UI

10%

Testing Types

• “They’re good when the problem is easy”

– A rabbit hole of testing

• “I spend too much time writing lots of code

to test, so I give up”

• “There’s just some stuff you can’t unit test”

Great Unit Testing Myths

Mocking makes unit testing easier!

12

What Are Mocks?

13

Test Double

Dummy

ObjectTest Stub Test Spy

Mock

Object

Fake

Object

Commonly referred to as “Mocks”

• Stubs

– Provide a canned response to method calls

• Spy

– Real objects that behave like normal except

when a specific condition is met

• Mocks

– Verifies behavior (calls) to a method

What Are Mocks?

14

Blah Blah Blah professor Dan…

15

• Eliminates dependencies in the CUT

(class under test)

– Isolated Unit Tests

Problems Mocks Solve

16

foo(x) bar(x)

• Tests methods that have no return value

Problems Mocks Solve

17

How do we know that bar(x) has been called?

• Tests error handling

Problems Mocks Solve

18

How do we generate this exception???

• Eliminate dependency on database calls

– Speed up testing!

• Reduce test complexity

– Don’t have to write complex logic to handle

behavior of methods not under test

• Don’t have to wait to implement other

methods

Other Reasons Mocks Are Important

19

Ok, I’m sold…Show me how to actually do this…

20

• Mock (MagicMock)– Most robust, popular

– Built-in as of Python 3.3!

• flexmock– Based on Ruby’s flexmock

• mox– Similar to Java’s EasyMock

• Mocker

• dingus– “record then assert” mocking library

• fudge– Similar to Mockito

• MiniMock– Simple mocking with DocTest

What Are The Python Options?

21

Sample Problem

22

Valentine’s Day Edition

Problem: Tinder Competitor

23

Get yo’ container on…

• Create a method to return a new, random

victim candidate

– Must not show the same person

– Must not show someone the user has already

“swiped” on

Problem: “Docker” dating app

Easy enough…

25

“Surely no one could

have seen EVERYONE

in the database!!!”

- The Internget_next_person() get_random_person()

Write a Unit Test…

26

It works!!!

27

29

Easy enough…

30

What if knew the result of get_random_person()???

31

PatchingModule.attribute

Mock method

It works EVERY SINGLE TIME!!!

33

Variations on a theme

34

Variations on a theme

35

Variations on a theme

36

Variations on a theme

37

OMG, ContextManagers! WHAT???

But what if we call it multiple times???

38

• What if I want to test the while loop?

Different results on multiple calls

Uh…umm…

40

UMM…

Use side_effect

41

• Use patching / mocks to bring certainty to

method calls

• Eliminates dependencies on other code

– Even unfinished code!!!

• Lots of ways to do it, pick your favorite

Recap: What did we learn?

42

Mocking to Verify Behavior

43

Problem: Matching in “Docker”

• When a user swipes right…

• If the other user “likes” them:

– Send them both a message with contact info

• If the other user “dislikes” them:

– Let the user down gently…

• If the other user hasn’t evaluated yet:

– Display the “give it time” message

Problem: “Docker” matches

Implementation

46

How do we test this??? No return values!!!

Behavior Verification

47

What about checking parameters???

48

Verifying Parameters

49

Shouldn’t we check the other

methods too?

50

We’d need to have multiple mocks to do that!!!

Multiple Mocks

51

Patch Multiple

52

Testing Multiple Calls…

53

Multiple calls

54

Whew!!!Almost Done!There will be beer soon!

Sweet, delicious beer!

55

Mocking built-ins and Exceptions

56

Simple JSON reader

How do we test something like this???

• Test parsing a valid file

• Test an IOError (i.e. file missing)

• Test a ValueError (i.e invalid json)

Testing JSON reader

58

• Let’s just create a sample file!

How do I test open()

59

Can you even mock a builtin?

60

• open() returns a File object

• open(filename).read()

• So we really need to mock File.read()

– But it’s an instance!!! Oh no!

What? Why Not???

61

Have you tried solving it with Mocks???

Mocks returning Mocks? WAT???

62

What about error handling?

63

What about error handling?

64

What about ValueError?

Wrap Up:Key Take-Aways

66

• Mocking makes writing unit tests simpler

– Eliminates dependencies

– Verifies behavior

– Tests error handling

• You just need some practice!

Remember This!

• http://mock.readthedocs.org/en/latest/

• Pip Install Mock

• Create a simple class, then write tests!

Try It On Your Own

68

Let’s Go Write Some Tests!!!

69

Questions?

70