Managing Mocks
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Sherwood-Taylor, Helen
Helen Sherwood-Taylor - Managing Mocks Mocking is a valuable technique for writing tests but mocking effectively is often a stumbling block for many developers and can raise questions about its overall value as a technique. There will be a brief introduction to mocking, then a look at features and techniques of Python’s unittest.mock library and cover some useful tips and common scenarios, so this will be useful to those who have some experience mocking but would like to do so more effectively. - Mocking is a valuable technique for writing tests but mocking effectively is often a stumbling block for many developers and can raise questions about its overall value as a technique. The audience will have some familiarity with unit testing and may have tried mocking before, but some introduction will be provided for those who haven’t. We will look at some features and techniques of Python’s unittest.mock library and cover some useful tips and common scenarios, so this will be useful to those who have some experience mocking but would like to do so more effectively. Summary of proposed content: 1. A short introduction to what mocking is and why it is useful. 2. Tour of Python’s mock library and how to make the most of it * Creating and manipulating Mock objects * Setting up return values and side effects to control test environment * Inspecting mocks - different ways to examine a mock object and find out what happened during the test * How and where to patch 3. Common mocking situations - scenarios where mocking is particularly useful and/or tricky to get right. For example - date/time, filesystem, read only properties 4. Some discussion of when mocking is and isn't helpful. Focus will be mainly on Python's unittest.mock module but we will also have a brief look at some other useful libraries.
 We're going to get started with Helen and managing mocks. Please give her a big round of applause. Hi, everybody. My name is Helen. I'm a freelance programmer. I've been using Python for quite a few years. This is my first year at Python. I'm really excited to be speaking here and I'm really enjoying Bill Bowell and having a great week. So I decided to write this talk. I originally wrote it for Python UK last year. I did that not because I felt like I was an expert on mocking, but because it was something that I'd tried working with quite a lot and I'd struggled with and felt like I was sort of hacking my way around and not really taking the time to understand it properly. Then I started a new project and it had lots of API interactions and databases that I didn't own and things that were quite a good case for mocking. And so I wanted to start doing things nicely and write lots of tests and try and understand this properly. So it's something that I've struggled with and learned a lot about and I wanted to share a few of the things I've learned. So what is a mock? A mock is a fake object that replaces a real object and the main use for this is in unit testing. Mocks are a way to control and isolate the environment in which your test runs. So why would you want this? Well, first of all, you want your tests to be deterministic. If they are failing, it should be because there's something wrong with your code, not because of some external factor like a server being down. You need to be able to trust your tests. If you don't trust them, you'll start ignoring them. Mocking gives you more control over the inputs to your test. You can simulate different environments for your code and make sure it responds correctly to all kinds of scenarios. It's also fast. It's an in-memory operation, so it's generally quite a lot faster than the things it's replacing, like network calls and file systems. And the speed of your tests is really important. Again, if that's too slow, you'll start running them. So I'm mostly going to be talking about the mock library that comes with Python. This is called unittest.mark. Don't worry about the unit test name. You can use it with any framework. It works quite well with PyTest and other things. So it used to be a standalone library. It was written by Michael Ford, and it was brought into Python in 3.3. If you're using earlier versions, you can still use the standalone version, and that's actually maintained and kept up to date. So Python 3.3 plus, just do unittest.mark. Otherwise, pip install mark and then import mark. So we're going to start with a look at mock objects. You'll find yourself working with these quite a lot. So you import mock with a capital M, and that's the mock class. You set that up with whatever values you want it to have. So here I'm setting a value, and then I can get that back as a property of the mock. If you try to use a property that you haven't set, that's another mock. If you try to use one of its properties, that's also another mock. So it's mocks all the way down, and you can kind of dig down and set the values of these mocks and get them back. Mocks are also callable, and when you call a mock, it returns another mock. So we've got more mocks. If you want to change what your mock returns, then you can set its return value, and then when you call it, you'll get back the value that you set. So you can dig down as far as you want into this structure. You can just go as deep as you want, and this is all about setting up the right environment for your code to pick up on. Another way that you can set up what your mock does when it's called is side effects. So a side effect can be an exception. So if you assign an exception class to side effect on a mock, then when that mock is called, you'll get that exception raised. It can also be a function, so you can override the behavior of that. I don't find I use this a lot, but it is terribly needed. And a side effect can also be a list of things you want to happen. Now this is useful if your code is going to be making multiple calls to this mock, and you want a different thing to happen each time. So I can set up side effect with a value, an exception, and then another value. So the first time I call it, I get the value. Second time, it will raise the exception. Third time, I get another value. And if I try to call it again, I'll get a stop iteration because I ran out of side effects. And if you want it to go on forever, it's just an iterable, so you can have a cycle or something. So while you're doing things to mocks, they are recording everything that's happening to them. They record all the calls that are made and all the arguments that are passed in. And you can get that information, you can query that information using these assertion calls. And most of them want you to say which arguments you expected them to be called with. So we've got a cert called with, which looks at the last call that was made. It doesn't care what happened before that. You've got a cert called once with, which is the same, but it makes sure that it was only called once. You've got a cert any call, which just looks at whether that call was ever made with those arguments, doesn't care about the others. You've got a cert has calls, which you can give it a list of calls, and you can specify whether you care about the order. Then you've got a cert not called, which just you check that it wasn't called. You need to be a little bit careful with that last one because, so if you do this in Python 3.5, you create a mock, you call it, and then you assert that it wasn't called, you get an assertion error, and that's kind of what we might expect to happen. You do the same thing in Python 3.4. You create the mock, you call it, you assert not called. All that happens is that you get back another mock, and if that's in a test, it will just run and it won't fail. The reason for that is that a cert not called didn't exist before Python 3.5, so when we try to use it, it just behaves like anything that we might try to access on the mock. That just passes, and that's maybe a little bit dangerous. If you do plan to use that call, make sure you know which versions of Python people are going to be developing with, and maybe just don't if you can't. So that's a little bit dangerous, and it has caught me out a couple of times, probably because I wasn't doing Red Green TDD properly, which is bad. Then 3.5 thankfully does something about this. So we get these safety checks. If you try to call something beginning with assert or a threat, because you might make typos, it will complain. So we've got assert call, which is being added in Python 3.6. We try to use that in Python 3.5. We get an attribute error, and that's kind of good because it's telling us that something's wrong with our code. And if you really have things that are beginning with assert, and you want to use them, then there's a flag called unsafe you can use to switch that off. When you're using these assertion calls, you generally have to say which arguments you want to be passed in, you're expecting to be passed in, and they're generally fairly fancy about that. But sometimes you might not care about what one of the arguments was. Maybe your argument is particularly complex, so you're testing them all in separate tests. So you can use mock.any for that, and you can just pass that in, pass it in as in place of an argument, and that just says I don't care what the value of this argument is. If you want even more control there, you can use comparison objects. So these aren't really a special mock thing, they're just a nice Python thing with magic methods, which you might have been to other talks about this week. If you have an object, an instance of a class that implements the EQ magic method, then you can implement a custom comparison and pass that in as a check in your assertion checks. So for example here, I'm checking whether my function was called with a multiple of five, and it was, and then with a multiple of four, which it wasn't, and I've got a nice performative string to describe what went wrong as well. You can have even more control over the inspection of your calls. Maybe you want to work at a lower level. You can say, was this mock called, how many times was it called, and get access, raw access to all the arguments that it's called with. So we've looked at a lot of features of mock objects. Let's have a look at how they fit into your tests. As a general kind of pattern, we'll be creating a mock and making sure it's in the right place, then we'll be setting up the values on it, the environment for your test, then we run the code under test, and then we check that our expectations have been met. So first of all, let's look at how we get a mock into place. This we use patch. So this tells Python where to put a mock. You give it a path to a module or a class or a function or anything that can be looked up as a path. And it will set things up so that when that path is looked up, it will give you back, rather than giving you back the real thing, it will give you back a mock. And you get access to that mock in your test. So you can manipulate that mock and kind of get that injected into your code via patch. Now, the object it actually gives you is a magic mock, which is like a mock object, but it has some of the magic methods set up for convenience. But we don't need to worry too much about that. So there are a few different ways you can access patch, depending on what your situation is. First of all, we have a decorator. So I've got a little example function, which I'm going to be testing. It uses requests to contact the GitHub API. It fetches a JSON document for a user and extracts that user's number of followers and returns it. So it just looks like that when we run it. So we patch our test method using requests.get. We get a mock object passed into our test method as a parameter. We can then manipulate the values of the mock. So we chain all the way down through return values and objects and more return values and set up what we're going to pretend is being returned from this API. And then we can run our assertion and check that the right value came back. You can also move it up to the top of your test class if you've got one and have it as a class decorator. If all your test methods are patching the same thing, then that's quite handy. You can stack multiple patches. You need to be careful about the order in which you do that. It kind of works from the inside out. So the bottom most patch corresponds to the first parameter and so on. Patch kernels to be a context manager. So we get a mock into our context and that survives, the patch is active for the lifetime of the context. So this gives you more control over the lifetime of your mock if that's what you need. If you have any kind of clashes with other stuff that does clever things with parameters like pytest or other such things, that it can be quite handy there. I tend to use the decorator version when I can because I don't like long lines of code and these make your code longer. Okay, so you can have even more control with, by calling start and stop on the object returned by patch. I don't find that to use too much but it can be useful. One thing I particularly struggled with in mocking was patch paths and how the lookups work and what path to use when I'm patching. I often found that mocks weren't appearing where I was expecting them to and I was getting very confused so I just want to look at how this works. So I've got my getFORWords function again and it's in a module called githubutils and I've got a test for that. So the test imports githubutils. Githubutils imports requests and pulls it into its own namespace. Coming back to our test, we patch requests.get, we get our mock, we manipulate it and then we call getFollowers. GetFollowers looks up requests.get and because we patch that path, it will get back the mock so our test behaves as we might expect it to and it passes. If you consider a slightly different example where I've done a from request import get at the module level rather than looking up inside the function, the test is almost exactly the same apart from the import. So if I import githubutils2, that imports get from requests, then our test patches requests.get, it gets the mock, manipulates it, calls getFollowers.getFollowers called get. Get's already been looked up on requests and it was looked up before we patched. So what's going to happen is we're going to get a slight delay and then we get something that doesn't match the value we set up. And that's because it was talking to the network because we patched. You might say we patched too soon. A better answer to that is that we patched the wrong thing. And this is how we fix that. We patch the thing that our module has already looked up. So we patch it on the module itself because it owns a thing called get. So our test looks like this and that works. The Python docs say ensure you patch the name used by the system under test. Another useful thing is patch.object. You can use this to attach a mock to another part of an object that you're already testing. For example, here I've got a simple greet function on my user class that says happy birthday to the user if it's their birthday. I'm testing that function and I want to mock his birthday. So I get a user object. I patch it by passing in the object itself, the name of the method I want to patch, and the return value I want it to have. And when I get inside that context, the user.isBirthday is a magic mock that will return true. So that will make my test work. Mocking the time can be quite tricky. The date module is written in C, so you can't mock individual bits of it. If you try, you'll probably get something like this. You can mock the whole thing, but it does mean you've got to kind of chain all the way down to the bit you want and you don't get a choice at whether you're mocking the other bits. So using the birthday-based method. So I patch that. I modify the return value of today and that works. A possibly nicer way of doing that is the freeze-gun library, which is pretty cool. You pip install freeze-gun and it comes with a decorator called freeze-time. That takes all sorts of interesting human-friendly formats that you can put in. You can have dates and date times and so on. And it's pretty straightforward to use. I like that library. Mocking the file system is also quite tricky. There's a utility method called mock open, which helps you out here. You give it a parameter called readData, which you can tell it what data you want to pretend your file has, and it will set up a special mock that has all the right sort of file handled stuff. Because we're using open, which is a built-in, we need to do something slightly different when we patch that. We need to use create equals true because we can't overwrite the built-in. We need to kind of create a local copy of open that our code is going to pick up on. Then once we've got that, we can open and read our file. There's one little problem with this. You can't iterate over that file handle. Your file handling code probably has a nice, pythonic interface like this. If you want that, then you've got to modify the mock that you get back from mock open and chain all the way down to the itter magic method and set up the lines that you want. But if you're doing that in the context manager, you need to go through the enter magic method as well. If you want to mock a property, so we've got our person class again. I've made his birthday a property now. If you try to patch the object, that doesn't work. You get this error not entirely sure why. I guess it's something to do with the way that properties work. You need special handling for that. For that, there's a parameter called new callable, which lets you say what type of mock you want to create. That's a special mock class called property mock set up just for this purpose. The other thing there is you need to patch the class rather than the object, which might be a little bit limiting. But as far as I know, that's the only way to do that. I've just got a little example of some mock-based test. I've got this very crude retry function, you pass it another function, and it tries over and over to call it until it succeeds. If you get a database error, it will wait a little bit and then try again, and it will keep doubling that delay. When we're thinking about testing this, I can see two big reasons for mocking. First of all, we've got this time.sleep, which if it's in our test, then it's going to slow our test suite down. Secondly, we want to be able to simulate database errors. We don't want to cause real database errors. This is a test that I've written for this function. We patch time.sleep, and that gets rid of the delays for us. We get a mock object passed in as our parameter. We create another mock inside the function. This is going to be the function that's going to be run each time. We set it up with three side effects, two failures followed by a success. We call our retry function, and then we have a look at what happened. First, we check that it was called three times because we had two failures and then a success. Then mock.sleep assert has calls. We're just checking the calls, the delays that were made, and making sure that it was doubled each time. Then we check that the result that came back was what we set up as a return value for that function. That's just a little example for you. I'm nearly out of time, so I had some little bit of stuff about when you mock and why you should mock. I'm going to post these slides online afterwards and also got some recommended reading for you. The testing notebook by Harry Percival is very good and talks quite a lot about why you should mock and the advantages of mock and how it can help drive better design. Harry Bernhardt, fast test, slow test is a very good talk about the same sort of things. It's worth watching. The unit test on mock library, I couldn't possibly cover every feature of mock in this time that I've tried, but it's a great read. I'm Helen Estee on Twitter and GitHub, and there's also a GitHub repository of the iPython notebooks with this material. The slides are quite dense, so there's some sort of interactive examples in there. Thank you. Thanks very much. Please thank the speaker.
 We're going to get started with Helen and managing mocks.  Please give her a big round of applause.  Hi, everybody.  My name is Helen.  I'm a freelance programmer.  I've been using Python for quite a few years.  This is my first year at Python.  I'm really excited to be speaking here and I'm really enjoying Bill Bowell and having  a great week.  So I decided to write this talk.  I originally wrote it for Python UK last year.  I did that not because I felt like I was an expert on mocking, but because it was something  that I'd tried working with quite a lot and I'd struggled with and felt like I was sort  of hacking my way around and not really taking the time to understand it properly.  Then I started a new project and it had lots of API interactions and databases that I didn't  own and things that were quite a good case for mocking.  And so I wanted to start doing things nicely and write lots of tests and try and understand  this properly.  So it's something that I've struggled with and learned a lot about and I wanted to share  a few of the things I've learned.  So what is a mock?  A mock is a fake object that replaces a real object and the main use for this is in unit  testing.  Mocks are a way to control and isolate the environment in which your test runs.  So why would you want this?  Well, first of all, you want your tests to be deterministic.  If they are failing, it should be because there's something wrong with your code, not  because of some external factor like a server being down.  You need to be able to trust your tests.  If you don't trust them, you'll start ignoring them.  Mocking gives you more control over the inputs to your test.  You can simulate different environments for your code and make sure it responds correctly  to all kinds of scenarios.  It's also fast.  It's an in-memory operation, so it's generally quite a lot faster than the things it's replacing,  like network calls and file systems.  And the speed of your tests is really important.  Again, if that's too slow, you'll start running them.  So I'm mostly going to be talking about the mock library that comes with Python.  This is called unittest.mark.  Don't worry about the unit test name.  You can use it with any framework.  It works quite well with PyTest and other things.  So it used to be a standalone library.  It was written by Michael Ford, and it was brought into Python in 3.3.  If you're using earlier versions, you can still use the standalone version, and that's  actually maintained and kept up to date.  So Python 3.3 plus, just do unittest.mark.  Otherwise, pip install mark and then import mark.  So we're going to start with a look at mock objects.  You'll find yourself working with these quite a lot.  So you import mock with a capital M, and that's the mock class.  You set that up with whatever values you want it to have.  So here I'm setting a value, and then I can get that back as a property of the mock.  If you try to use a property that you haven't set, that's another mock.  If you try to use one of its properties, that's also another mock.  So it's mocks all the way down, and you can kind of dig down and set the values of these  mocks and get them back.  Mocks are also callable, and when you call a mock, it returns another mock.  So we've got more mocks.  If you want to change what your mock returns, then you can set its return value, and then  when you call it, you'll get back the value that you set.  So you can dig down as far as you want into this structure.  You can just go as deep as you want, and this is all about setting up the right environment  for your code to pick up on.  Another way that you can set up what your mock does when it's called is side effects.  So a side effect can be an exception.  So if you assign an exception class to side effect on a mock, then when that mock is called,  you'll get that exception raised.  It can also be a function, so you can override the behavior of that.  I don't find I use this a lot, but it is terribly needed.  And a side effect can also be a list of things you want to happen.  Now this is useful if your code is going to be making multiple calls to this mock, and  you want a different thing to happen each time.  So I can set up side effect with a value, an exception, and then another value.  So the first time I call it, I get the value.  Second time, it will raise the exception.  Third time, I get another value.  And if I try to call it again, I'll get a stop iteration because I ran out of side effects.  And if you want it to go on forever, it's just an iterable, so you can have a cycle  or something.  So while you're doing things to mocks, they are recording everything that's happening  to them.  They record all the calls that are made and all the arguments that are passed in.  And you can get that information, you can query that information using these assertion  calls.  And most of them want you to say which arguments you expected them to be called with.  So we've got a cert called with, which looks at the last call that was made.  It doesn't care what happened before that.  You've got a cert called once with, which is the same, but it makes sure that it was  only called once.  You've got a cert any call, which just looks at whether that call was ever made with those  arguments, doesn't care about the others.  You've got a cert has calls, which you can give it a list of calls, and you can specify  whether you care about the order.  Then you've got a cert not called, which just you check that it wasn't called.  You need to be a little bit careful with that last one because, so if you do this in Python  3.5, you create a mock, you call it, and then you assert that it wasn't called, you get  an assertion error, and that's kind of what we might expect to happen.  You do the same thing in Python 3.4.  You create the mock, you call it, you assert not called.  All that happens is that you get back another mock, and if that's in a test, it will just  run and it won't fail.  The reason for that is that a cert not called didn't exist before Python 3.5, so when we  try to use it, it just behaves like anything that we might try to access on the mock.  That just passes, and that's maybe a little bit dangerous.  If you do plan to use that call, make sure you know which versions of Python people are  going to be developing with, and maybe just don't if you can't.  So that's a little bit dangerous, and it has caught me out a couple of times, probably  because I wasn't doing Red Green TDD properly, which is bad.  Then 3.5 thankfully does something about this.  So we get these safety checks.  If you try to call something beginning with assert or a threat, because you might make  typos, it will complain.  So we've got assert call, which is being added in Python 3.6.  We try to use that in Python 3.5.  We get an attribute error, and that's kind of good because it's telling us that something's  wrong with our code.  And if you really have things that are beginning with assert, and you want to use them, then  there's a flag called unsafe you can use to switch that off.  When you're using these assertion calls, you generally have to say which arguments you  want to be passed in, you're expecting to be passed in, and they're generally fairly  fancy about that.  But sometimes you might not care about what one of the arguments was.  Maybe your argument is particularly complex, so you're testing them all in separate tests.  So you can use mock.any for that, and you can just pass that in, pass it in as in place  of an argument, and that just says I don't care what the value of this argument is.  If you want even more control there, you can use comparison objects.  So these aren't really a special mock thing, they're just a nice Python thing with magic  methods, which you might have been to other talks about this week.  If you have an object, an instance of a class that implements the EQ magic method, then  you can implement a custom comparison and pass that in as a check in your assertion checks.  So for example here, I'm checking whether my function was called with a multiple of  five, and it was, and then with a multiple of four, which it wasn't, and I've got a nice  performative string to describe what went wrong as well.  You can have even more control over the inspection of your calls.  Maybe you want to work at a lower level.  You can say, was this mock called, how many times was it called, and get access, raw access  to all the arguments that it's called with.  So we've looked at a lot of features of mock objects.  Let's have a look at how they fit into your tests.  As a general kind of pattern, we'll be creating a mock and making sure it's in the right place,  then we'll be setting up the values on it, the environment for your test, then we run  the code under test, and then we check that our expectations have been met.  So first of all, let's look at how we get a mock into place.  This we use patch.  So this tells Python where to put a mock.  You give it a path to a module or a class or a function or anything that can be looked  up as a path.  And it will set things up so that when that path is looked up, it will give you back, rather  than giving you back the real thing, it will give you back a mock.  And you get access to that mock in your test.  So you can manipulate that mock and kind of get that injected into your code via patch.  Now, the object it actually gives you is a magic mock, which is like a mock object,  but it has some of the magic methods set up for convenience.  But we don't need to worry too much about that.  So there are a few different ways you can access patch, depending on what your situation  is.  First of all, we have a decorator.  So I've got a little example function, which I'm going to be testing.  It uses requests to contact the GitHub API.  It fetches a JSON document for a user and extracts that user's number of followers and  returns it.  So it just looks like that when we run it.  So we patch our test method using requests.get.  We get a mock object passed into our test method as a parameter.  We can then manipulate the values of the mock.  So we chain all the way down through return values and objects and more return values  and set up what we're going to pretend is being returned from this API.  And then we can run our assertion and check that the right value came back.  You can also move it up to the top of your test class if you've got one and have it as  a class decorator.  If all your test methods are patching the same thing, then that's quite handy.  You can stack multiple patches.  You need to be careful about the order in which you do that.  It kind of works from the inside out.  So the bottom most patch corresponds to the first parameter and so on.  Patch kernels to be a context manager.  So we get a mock into our context and that survives, the patch is active for the lifetime  of the context.  So this gives you more control over the lifetime of your mock if that's what you need.  If you have any kind of clashes with other stuff that does clever things with parameters  like pytest or other such things, that it can be quite handy there.  I tend to use the decorator version when I can because I don't like long lines of code  and these make your code longer.  Okay, so you can have even more control with, by calling start and stop on the object returned  by patch.  I don't find that to use too much but it can be useful.  One thing I particularly struggled with in mocking was patch paths and how the lookups  work and what path to use when I'm patching.  I often found that mocks weren't appearing where I was expecting them to and I was getting  very confused so I just want to look at how this works.  So I've got my getFORWords function again and it's in a module called githubutils and  I've got a test for that.  So the test imports githubutils.  Githubutils imports requests and pulls it into its own namespace.  Coming back to our test, we patch requests.get, we get our mock, we manipulate it and then  we call getFollowers.  GetFollowers looks up requests.get and because we patch that path, it will get back the mock  so our test behaves as we might expect it to and it passes.  If you consider a slightly different example where I've done a from request import get at  the module level rather than looking up inside the function, the test is almost exactly the  same apart from the import.  So if I import githubutils2, that imports get from requests, then our test patches requests.get,  it gets the mock, manipulates it, calls getFollowers.getFollowers called get.  Get's already been looked up on requests and it was looked up before we patched.  So what's going to happen is we're going to get a slight delay and then we get something  that doesn't match the value we set up.  And that's because it was talking to the network because we patched.  You might say we patched too soon.  A better answer to that is that we patched the wrong thing.  And this is how we fix that.  We patch the thing that our module has already looked up.  So we patch it on the module itself because it owns a thing called get.  So our test looks like this and that works.  The Python docs say ensure you patch the name used by the system under test.  Another useful thing is patch.object.  You can use this to attach a mock to another part of an object that you're already testing.  For example, here I've got a simple greet function on my user class that says happy birthday  to the user if it's their birthday.  I'm testing that function and I want to mock his birthday.  So I get a user object.  I patch it by passing in the object itself, the name of the method I want to patch, and  the return value I want it to have.  And when I get inside that context, the user.isBirthday is a magic mock that will return true.  So that will make my test work.  Mocking the time can be quite tricky.  The date module is written in C, so you can't mock individual bits of it.  If you try, you'll probably get something like this.  You can mock the whole thing, but it does mean you've got to kind of chain all the way  down to the bit you want and you don't get a choice at whether you're mocking the other  bits.  So using the birthday-based method.  So I patch that.  I modify the return value of today and that works.  A possibly nicer way of doing that is the freeze-gun library, which is pretty cool.  You pip install freeze-gun and it comes with a decorator called freeze-time.  That takes all sorts of interesting human-friendly formats that you can put in.  You can have dates and date times and so on.  And it's pretty straightforward to use.  I like that library.  Mocking the file system is also quite tricky.  There's a utility method called mock open, which helps you out here.  You give it a parameter called readData, which you can tell it what data you want to pretend  your file has, and it will set up a special mock that has all the right sort of file handled  stuff.  Because we're using open, which is a built-in, we need to do something slightly different  when we patch that.  We need to use create equals true because we can't overwrite the built-in.  We need to kind of create a local copy of open that our code is going to pick up on.  Then once we've got that, we can open and read our file.  There's one little problem with this.  You can't iterate over that file handle.  Your file handling code probably has a nice, pythonic interface like this.  If you want that, then you've got to modify the mock that you get back from mock open  and chain all the way down to the itter magic method and set up the lines that you want.  But if you're doing that in the context manager, you need to go through the enter magic method  as well.  If you want to mock a property, so we've got our person class again.  I've made his birthday a property now.  If you try to patch the object, that doesn't work.  You get this error not entirely sure why.  I guess it's something to do with the way that properties work.  You need special handling for that.  For that, there's a parameter called new callable, which lets you say what type of mock you want  to create.  That's a special mock class called property mock set up just for this purpose.  The other thing there is you need to patch the class rather than the object, which might  be a little bit limiting.  But as far as I know, that's the only way to do that.  I've just got a little example of some mock-based test.  I've got this very crude retry function, you pass it another function, and it tries over  and over to call it until it succeeds.  If you get a database error, it will wait a little bit and then try again, and it will  keep doubling that delay.  When we're thinking about testing this, I can see two big reasons for mocking.  First of all, we've got this time.sleep, which if it's in our test, then it's going to slow  our test suite down.  Secondly, we want to be able to simulate database errors.  We don't want to cause real database errors.  This is a test that I've written for this function.  We patch time.sleep, and that gets rid of the delays for us.  We get a mock object passed in as our parameter.  We create another mock inside the function.  This is going to be the function that's going to be run each time.  We set it up with three side effects, two failures followed by a success.  We call our retry function, and then we have a look at what happened.  First, we check that it was called three times because we had two failures and then a success.  Then mock.sleep assert has calls.  We're just checking the calls, the delays that were made, and making sure that it was  doubled each time.  Then we check that the result that came back was what we set up as a return value for that  function.  That's just a little example for you.  I'm nearly out of time, so I had some little bit of stuff about when you mock and why you  should mock.  I'm going to post these slides online afterwards and also got some recommended reading for  you.  The testing notebook by Harry Percival is very good and talks quite a lot about why you should  mock and the advantages of mock and how it can help drive better design.  Harry Bernhardt, fast test, slow test is a very good talk about the same sort of things.  It's worth watching.  The unit test on mock library, I couldn't possibly cover every feature of mock in this  time that I've tried, but it's a great read.  I'm Helen Estee on Twitter and GitHub, and there's also a GitHub repository of the iPython  notebooks with this material.  The slides are quite dense, so there's some sort of interactive examples in there.  Thank you.  Thanks very much.  Please thank the speaker.
Helen_Sherwood-Taylor_-_Managing_Mocks_0_16571.png Helen_Sherwood-Taylor_-_Managing_Mocks_16572_16955.png Helen_Sherwood-Taylor_-_Managing_Mocks_16956_27443.png Helen_Sherwood-Taylor_-_Managing_Mocks_27444_28103.png Helen_Sherwood-Taylor_-_Managing_Mocks_28104_28283.png Helen_Sherwood-Taylor_-_Managing_Mocks_28284_28355.png Helen_Sherwood-Taylor_-_Managing_Mocks_28356_28439.png Helen_Sherwood-Taylor_-_Managing_Mocks_28440_28571.png Helen_Sherwood-Taylor_-_Managing_Mocks_28572_28619.png Helen_Sherwood-Taylor_-_Managing_Mocks_28620_28715.png Helen_Sherwood-Taylor_-_Managing_Mocks_28716_29087.png Helen_Sherwood-Taylor_-_Managing_Mocks_29088_29627.png Helen_Sherwood-Taylor_-_Managing_Mocks_29628_29879.png Helen_Sherwood-Taylor_-_Managing_Mocks_29880_31031.png Helen_Sherwood-Taylor_-_Managing_Mocks_31032_31079.png Helen_Sherwood-Taylor_-_Managing_Mocks_31080_31679.png Helen_Sherwood-Taylor_-_Managing_Mocks_31680_32459.png Helen_Sherwood-Taylor_-_Managing_Mocks_32460_32663.png Helen_Sherwood-Taylor_-_Managing_Mocks_32664_32735.png Helen_Sherwood-Taylor_-_Managing_Mocks_32736_32915.png Helen_Sherwood-Taylor_-_Managing_Mocks_32916_33131.png Helen_Sherwood-Taylor_-_Managing_Mocks_33132_33179.png Helen_Sherwood-Taylor_-_Managing_Mocks_33180_33287.png Helen_Sherwood-Taylor_-_Managing_Mocks_33288_33839.png Helen_Sherwood-Taylor_-_Managing_Mocks_33840_36191.png Helen_Sherwood-Taylor_-_Managing_Mocks_36192_36323.png Helen_Sherwood-Taylor_-_Managing_Mocks_36324_36407.png Helen_Sherwood-Taylor_-_Managing_Mocks_36408_36983.png Helen_Sherwood-Taylor_-_Managing_Mocks_36984_37031.png Helen_Sherwood-Taylor_-_Managing_Mocks_37032_37211.png Helen_Sherwood-Taylor_-_Managing_Mocks_37212_37379.png Helen_Sherwood-Taylor_-_Managing_Mocks_37380_37799.png Helen_Sherwood-Taylor_-_Managing_Mocks_37800_37847.png Helen_Sherwood-Taylor_-_Managing_Mocks_37848_37924.png