Building data-driven web apps with Flask and SQLAlchemy Transcripts
Chapter: Testing web apps
Lecture: Avoiding the database call on register

Login or purchase this course to watch this video and the rest of the course contents.
0:00 All right, so there's a problem
0:01 trying to write this test and it's getting hard.
0:04 So, we try to run their test
0:06 and the problem is
0:07 way down here we're trying to create a database session.
0:10 Why are we trying to create a database session?
0:11 Well, over here we're trying to find the user by email.
0:15 Why are we doing that?
0:16 Because the view model wants to make sure
0:18 that you're not already registering
0:20 as a user that already exists.
0:23 But what are we going to do here? Do we have to just enable the database for our test?
0:26 No, hopefully we don't. What we can do is
0:30 we can actually go to this method here
0:33 and we can replace it with another one.
0:35 There's a bunch of options for this
0:36 but there's a really slick way when we're doing a unit test.
0:40 Let's go over here and say import unittest.
0:43 This is the built-in one
0:44 we're not actually using its main features
0:46 but we're going to use this mock feature here.
0:49 What mocking does is it says
0:51 I would like to replace a function's behavior
0:53 with another function that I'm writing.
0:56 or something along those lines.
0:58 So, what we can do down here is we can say with.
1:01 Actually, let's set up the target.
1:04 It's going to be, well it's going to be that function
1:07 that we tried to call over here.
1:08 It's going to be, where is this?
1:10 pypi_org.services.user_service.find_by_email
1:16 So we just got to type that out.
1:18 pypi_org.services.user_service
1:26 or we might be able to find it in our errors down here.
1:33 If we scrub that will be a little bit of a help
1:35 but anyway we can type it out here.
1:37 And what we do is we say, with unittest.mock.patch
1:42 and we're going to replace this function
1:45 and we say the return value is going to be none.
1:50 And then within that context manager
1:55 when I call this function.
1:57 So only will we change the behavior
2:00 of find user by email right here
2:02 soon this context manager is with block
2:05 it goes back to talking to the database.
2:07 So this means we don't permanently change it
2:10 maybe alter the behavior of other task writes
2:13 only isolated right here which is perfect.
2:16 Let's try this now.
2:17 This test should work unless I've messed that up.
2:21 Tada! Look at that.
2:23 It works when the user is there.
2:25 Now what if we told it to return found, right.
2:29 Some other user obviously, it's the wrong type
2:31 but it will still crash and say something to the effect of
2:34 a user with that email address already exists.
2:37 See how cool it is. We just control what the dependencies
2:41 are trying to do from the outside.
2:43 We could do this if we're trying to talk to an API
2:46 like Stripe for charging a credit card
2:47 we could do this for other APIs.
2:49 All the stuff that we were trying to call
2:51 as long as we build our code up in a decent way
2:55 we should be able to get in here
2:57 change just a function or two and make it work.
3:00 So this is great.
3:01 We're able to run our tests in complete isolation, right.
3:04 Our tests are passing
3:05 and the meaningful one here is working.
3:08 What we're doing is we're creating a fake test context
3:11 so the view model thinks the request is happening
3:15 within Flask and then when it does its operations
3:18 we're mocking out one of its tendencies
3:20 the database to control how it behaves.
3:23 Now we have a nice test in isolation.