Edwin Jung - Mocking and Patching Pitfalls - PyCon 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I got accepted I kind of realized that probably should have spent some more time on the title and so I actually thought of a lot of other titles and thought I would start out by showing some of those with you so all those titles I think are appropriate in their own different ways I think one of my favorite ones is people's history of marking because this is going to be a technical talk but it's also partly kind of a story about some observations I've made the way people use mocks in real life so this talk is going to be full of opinions and speculation and it's also gonna be very biased if it's not yet obvious from those those titles so I'm hoping it all just at least sparked some conversations and make you think about different ways of using mark or reconsider how using mock and patch in your projects but the final title I wanted was mock hell and it just didn't happen to make it into the program and that title is actually based on a comment co-worker of mine and once made where she said I am in mock hell so I'm a staff sovereign jurek quit working on platform what quit does is provide tools for understanding large amounts of unstructured text so what you see up here is a visualization which shows the clustering discussions around the future of air travel and that's based on I believe it's data sources from public news and blogs so on my day to day I work on a mix of data engineering and micro services what that means is that do 99 percent Python also flask and a little bit Scala and Java occasionally I'm also a relative newcomer to Python it's actually the fourth language I learned and I've only been doing it about four or five years professionally before that I did a ton of C++ and a little a job a little bit of Java and c-sharp and I think that kind of background working with statically compiled languages creates a different sort of perspective around software design and testing and I'm hoping to share some of those ideas here so who you might be this talk is gonna be more of an intermediate-to-advanced talk so you should at least used mocking or passion before if you haven't I think you can still learn some things and follow along maybe you're somebody whose uses the malcolm patch api regularly but you're not sure exactly why it's painful or why it causes you problems sometimes or maybe you're just really comfortable with mark but you want to learn more about different options and opinions on the way that they can be used some of the things you might learn or what are the different styles of unit testing or different styles of TDD where did marks actually come from and what are some alternatives and mocking what are some enter any patterns of marking and patching and what is the relationship between marking and good design so just like Dante had nine circles of progressive hell I think there's progressive levels of marquel and this is what I would personally consider marquel so right at the entrance you have complex past targets I think that's something everybody deals with and you just learn learn how to do it and it's it's not the worst thing but it is confusing where things get really bad is when you get to the bottom and the worst-case scenarios for me our situations where I end up having to use the debugger to reverse engineer the mocks and it tests or when there's just so much mocking that I don't even want to refactor the code because it's gonna result in changes across dozens and dozens of lines of code or files and so on so that's the scenario where the marks are actually technical debt so after running in this kind of issue over and over again in code I ban to ask myself this question of you know wire developers ending up with these problems all the time and how are they learning about mocks because when I wrote my own code I would rarely use marks or patches and what I did I wouldn't have all these these kinds of issues so I started reading a lot of books and blogs and just trying to figure this out and so I think when it comes to learning about mocks what happens is that people go out and they look at a blog or they look at a book or watch some videos and then they learn this mock is this really cool library used to isolate code for testing here's how you use magic mark patch spec Auto specs that effect and all those things and then there's some warning about patching being tricky you have to make sure you target the right namespace and there's typically some kind of example like this so you have some code under tests my module and that uses some other module called DB and a function DB read the code under test is this total value function and all what's going to do is pull a list of values based on some item ID and sum them up and return them and so here's a typical example of pretty straightforward example of how you'd use mock and patch so in this total value function our test total value function first thing you do is you apply a pouch around my module DB read that substitutes in this mock which I'm also calling DB read here and the first line of the actual test you set up a candy value to be returned you execute the code and assert on the return value and then finally you assert on the side-effects or the interaction with this DB read function so if I draw that as a picture this is kind of how I think about it so you've got total value in DB read and then the external database and white you write your tests that test sets up a patch around that DB read function you substitute Center mark runs the actual total value function certs on the results and then asserts on the interaction so the next thing that might happen is you might take that knowledge and go off and try to apply it to a real problem and so I cooked up a sort of simple example that's a little bit more realistic so the code is going to be a a bit more dense but that example is called a guardian feed and the Guardian is an English news website and they also provide a REST API that lets you search their entire database of articles so a hypothetical problem here is given some topic of interest like brexit find all the relevant articles from particular time period and feed those article URLs to a web scraper service so you can get all the content the rest api is pretty straightforward you just get on a search route and then there's some parameters in the query string to configure the date range also a page number that you want to get because there might be multiple pages or results your actual query string and an API key and this is what the response looks like the important parts here are that there's just a response blob it has a current page number to tell you which page you're on the total number of pages for that search query and then finally a results array or each element of that results array is going to have this web URL field and that's the field that you want to pull and provide to the scraper here's the main program it's pretty straightforward you just construct your feed with your query and then you run it and then there's here's the feed class if there's only three functions that's a lot of code so I've kind of broken it down with attend code folder so here's the constructor it takes a query parameter for the page size which is the number of results per page the date range you want to search over and then finally the host name for the Redis toast which is where we're gonna push all those URLs to so the constructor just set some internal parameters and then in the last two lines of the constructor it actually constructs a Redis connection and in a requests session which is going to hang on to a connection pool for the repeated requests that we make to this API the format request function is basically just taking all those parameters and a page number and it's going to build up a request HTTP GET and so that's what you see in the last line of this function where it's calling request dot prepare and then finally here's the run function and this is where all the work actually happens so this while loop is just iterating until it gets all the pages for that search query so the first two lines of that body are just sending they're just formatting a request and then sending it off to the Guardian then the next chunk there is just parsing the response to get that results field and then the very last chunk is just parsing the web URL field from each element of results and then pushing it to Redis the syntax in that last chunk is a little bit strange just because I needed to fit everything onto a single slide so okay so if I was going to draw that as a picture I might look like this I got the tests I got the feed I've got requests session requests requests and read SPI then my external systems in whites so if I follow the same pattern that we just looked at I want to apply my patches around these dependencies to isolate my feed class then I'm going to sub in a mock run the test and there's no return value here so I'm just going to assert on the interactions or side-effects of running that feed class so what that tests might actually look like if you're writing it so we want to test this feed run function and we know we're going to need to pass these things first thing we need to do is set up a return value for the response so this is just a fake response that's returning one page with two results after actually calling the run function it should hit the request API as a side-effect so that I'm going to make some assertions on those side effects so first thing I do is I assert that the prepare method was called then and I checked out the request message was constructed correctly with the expected parameters I want it to be make sure it's a get message it was using the correct Guardian ul URL and then I got the right parameters that I expected and I also want to assert on the Redis call so next year I was constructed correctly and make sure it got called with those two URLs that I would expect so that's that's a lot of code and I think it's it's representative of what I would call ma cow and I think it's a fair thing to say that it's is pretty heavily over marked and over patched and so when I end up dealing with code like this on a much larger scale this is kind of the the mood I get into and I feel kind of dazed I don't know what happened I don't know why the code is like that and it gets kind of tedious and that example is actually only probably like level 4 of mekele the more complex examples are just it's just too hard to explain in this kind of format so the question now is you know how do you fix something like that or how do you avoid it but before getting at that I think it's really helpful that be able to ask specific questions that help you name problems in this code other than saying oh it's really Maxine complex you know what do I do about it so the first question is how many marks do you think are in this code and just by show of hands who thinks it's three I thinks it's four and who think it's more than four okay so we have I think we have a lot of people who know me well it's actually 11 and this is this is because of this this deep mocking behavior of a mock and it's kind of a mixed bag of a being both a feature and a liability because it it it will automatically create another mock for you when you call undefined method and and that's nice for setting up your test but when you have a lot of them it becomes very confusing so I've also highlighted all the lines of mocking pouch and so the question when I see something like this that I have is is this is this actually essential behavior that my tests should care about or should know about or is it just implementation detail and I'm going to call it a couple of things here the set of patch statements is that is that really necessary information that the test needs to know about or is that just some kind of violation of an information hunting principle or encapsulation of the feed class these other lines I think arguably you could claim that these things are a law of Demeter violation and so what that is is some idea that comes out of object-oriented design about chaining method calls into an object's instance variables and the reasons that's not a good thing is because it's very invasive because you're reaching deep into an object hierarchy another way to think about this is how can you trivially break this this test with very sort of harmless refactorings so you know what if you change imports on Redis from this to this so it's pretty innocent refactoring but that's going to break your test at this patch another example of that is what if you change this request constructor to use args instead of quarks so something like this it's going to break this particular mark statement all right so this is an example of a really brittle specification or something that's over over verified I think and there's multiple more examples for that particular code base I could show you so I think what's happening when people are learning about mock and patch is that they're missing the fine print right and the fine print is sometimes comes across is something like oh by the way okay I think my text isn't showing up but is it's okay so there's a bullet point up there that says four and the fine print so it really is fine print but uh right there's typically some advice that says by the way be careful about over marking and I think that advice often comes in at the very end and it's an afterthought or it just gets ignored or it's not well understood and there's also a fifth bullet point on there called mocks aren't stubs which I'll get to in another eventually slide so another thing I did was you know before putting this deck together was go watch every video I could find about mocking at previous PI cons and the reason was I I wanted to make sure I wasn't just repeating existing information or saying anything crazy and I think for the most part it confirm confirm the pattern that I just saw about this this fine print last year there was a talk at PyCon Cleveland called demystifying the patch function and this is actually a good talk especially if you're confused about how to use the patch API and I actually learned some things from it that I used and some of the following examples and I also want to say thank you to Lisa Roach who gave this talk because I asked her to take a look at my slides and offer some feedback and she was nice enough to do it so the only reason I'm picking on this particular talk is because it did happen in Cleveland and something really interesting happen in the Q&A so the first thing that happened the Q&A was somebody came up and said hey I got all these problems patches no and and maintenance and technical debt what do I do about it you have any tips advice was this patches can definitely get out of hand you maybe need to look into why there are so much heavy mocking so this by itself is not that interesting other than the fact that it's an example of the fine print that I think often comes at the end the interesting part is is what actually happens next which is that somebody comes up to make a comment and that's a question and what they say is hello that was a really good talk on Michael Ford I was the original author of Mark one thing I would say is that patches are a sign of failure the more we have to patch the worse your code is so I think all that advice is spot-on and it's right but I also think it's it's unsatisfying in a way because it's it's very cryptic and if you're having problems with mark it's not really clear what you're supposed to do next to try and fix your poems so what I want to do is kind of dig in to what those things mean like what does it mean that patches are sign of failure or maybe you need to look into why there's so much heavy marking so do that I think you need to look at this question of where did mocks come from and really the idea behind mocking was that ideally there should be some kind of symbiotic relationship between your coding your tests or your tests reflecting the quality of your code which is signal that you should go back and we factor it and then your code is determining what your tests look like sometimes you'll hear that advice is this phrase called listening your tests right and where that phrase comes from is actually this book growing object entered software gotta by toughs by Freeman in price and these are the guys who actually invented mocking so if you go to appendix a they will actually tell you about the history of how they came up with the ideas and how they were doing in the context of doing extreme programming and TDD and object-oriented design in Java so you'll see the ideas in here refer to as as Marcus style sometimes you'll also hear it referred to as a London style teehee where they published that book they actually wrote this academic paper called mock rolls not objects I think the abstract has three really important points that are useful for understanding why people get getting to mock hell or have problems with mocks so the first two are that mock objects is an extension to test-driven development that supports good object-oriented design the third point they make is that it turns out to be less interesting as a technique for isolating tests then as web we thought and I think that's really important to understand because that's directly opposite of what you'll read if you go out and you just find some blog post or something about how to use mock or why mock and patch exist and I put those three points up on the slide just because I think they're important all right so marks were created in the context of doing TDD and object-oriented design and they were not really ever intended as to just be some tool for isolation so if you think about the things that those three points bring you if you're doing TDD you're doing rapid cycles of small refactoring if you're doing object-oriented design there's there's lots of things that brings but the important one is this idea of object collaborations or role based designs so if you've ever heard of things like CRC cards it's basically the same thing and then finally the way marks are intended to be used is that they're supposed to be a tool for exploratory design and discovery and so those three things together form this kind of what I would say a three legged stool to where if there's any sort of misunderstanding or deficiency and winning any one of those things things start to fall over and fall apart now there's also contrary opinions to that that London style of TDD and so not everybody likes this right so this book is a book with examples in c-sharp and I like this book because it has pretty subtle and nuanced view and then the thing they say is always choose interaction testing or mocking as the last option this is very important not everyone agrees with this point of view if you're gonna price would advocate like many call the London School I'm not fully disagreeing but for maintainability test using mocks creates more trouble than it's worth and I just put this up here because it's making a very strong statement which I think you will probably not ever gonna find in and Python material about mocking alright so if you're on board with this idea of not locking mocks or you want to get rid of marks question might be how do you test without marks so we're almost to the code and this is I think the last thing in this idea of marks aren't stubs which is line item five in the fine print alright so point one about marks aren't stubs is that mocks or not stubs point two is that marks do not equal stubs and number three is stubs are not marks so the reason I'm being a little bit pedantic about this because this is an important point in it it's important to understanding the rest of the slides and what this title is referring to as a blog post that talks about test doubles so if you're not familiar with test doubles basically a test level is just a thing you can substitute for the real thing and your test and as it turns out a mock is just one kind of double the Python mock library is a little bit confusingly names because you can actually configure it to behave like any one of these doubles it just uses different vocabulary and terminology and it makes a little bit hard to talk about these things I'm going to throw those definitions up here and just demonstrate them by example but they're here for reference in case you're looking at this later so if you go back to this mark couch example really what's going on here is in this first line you're setting up a stub and so what a stub is is just some can value that gets returned no matter what you're passing in all right the second line there is the Mach which is this DB read Det assert called with and so the important part of a Mach is that it's asserting on an interaction or a side effect with another system that's what makes this a Marcus style test or what some people call London style testing so what's the alternative to that it's something I'm going to call fake patching so if we bring this code back to something more minimal there's still this patch but I'm going to define this fake DB read function which is just actually has a little bit of logic to return a fixture from the file system and then I'm gonna use this feature called new of the patch function to substitute that in instead of using a mark so I'm still patching but I'm not marking and I only have a mr. show on the return value so I don't need to assert on this side effect or interaction so if I draw there's a picture it might look like this to find the fake substitute it in run it so on the results and that's it as a third alternative you can do dependency injection so you can actually inject your fake so do this you need to change the total value function so on the left is where we started and on the right is the modification so I just get rid of that DB import DB read import and then alter the signature of total value so that it expects to be provided with some collaborator that fills the role of a DB reader and so what that does is it completely decouples this my module package my module module from anything related to specific DB implementation and then when I actually inject it that the test is pretty pretty much the same except I provided as a parameter to the function call so I draw that as a picture it looks like this this total value function that expects to do a collaborator define the fake injected around the tests cert on the results on the real app you create a real DB adapter you inject it and then you just run all right so there's actually a fourth option which is you could inject a mock which you can figure out if you understand the previous three things so when it comes to dealing with with testing or refactoring code I find these three kinds of questions pretty handy number one is which test doubles do you want to be using all right so I should uh basically mocks and fakes you can go look out online and see what the other kinds are and think about how you might want to use those do you want to do maka store classical style testing sometimes it is also called London or Detroit so do you want to verify on side effects or do you just want to verify return values and state change and the last thing is do you want a patch or do you want to inject your test double once you've chosen it and you can mix and match these techniques to to get whatever results you need so that sets us up to go look at the Guardian feed test again so this is gonna be a little map of the things we're gonna look at and then I'm gonna use this plane to kind of keep track of where we are so the first thing is is mop rolls not objects so the easiest way to do that show that demonstrate others by example so the question on this is what are the roles in this collaboration I would say they're a master and student so Yoda and Luke are collaborators acting in the roles of master and student another part in this story obi-wan and Anakin were acting in the roles of Master and students and another point they were both sim same characters are acting in the roles of hero and villain but yet again and another point it was actually Luke and Darth Vader and then at the end they're acting in the rules of father and son are they're collaborating the roles of father and son so the question looking at this code is what are the roles in this collaboration and I would say the basic ones are you need something that's a parser or a connector something that's a data sink and something that's a source so if you're going to be marking or using a testable those are the abstractions do you want to be mocking so it sets us up to look at some of these other tactics and the first thing we're gonna attack is all the requests mocking and patching so we're gonna do two things one is this idea finding a seam and then we're gonna patch in a fake so this is where we left our tests and I'm gonna bring it back to something a little bit simpler and introduce this idea of a seam there's the collaborator we really wanna mock is the Guardian library and and not session or a request and sew a seam is this idea that comes out of refactoring and a scene is a place where you can alter behavior and your program without editing in that place so session is not just magically communicating The Guardian it's actually using a bunch of other libraries there's a lot of other levels of abstraction in-between so there's a couple different scenes we could exploit if you wanted to go really level you could try to use the TCP seemed easiest seem to use I think is to go in and patch our mock in the actual request internals inside that library instead of trying to mock our application and so there's a useful library called HTT mock that will let you do that so we're gonna make a change that looks like this and use that request scene to substitute a fake instead of a mark so this is what the fake function looks like it's just implementing a very simple logic to emulate the actual Guardian API the two lines that are important here are the first one which is this URL match which is directing HTT mark to redirect any traffic to this Guardian api's com hostname to this function and then this function gets a URL and the request body and we can do processing it and on it and whatnot to generate a faked response and return it so here's what the actual test looks like mock Redis is still there but this lets us get rid of all the patching and mocking around there boss library and replace it with that single patch statement and it lets me directly express the collaboration relationship that I actually care about so we're still patching we're just patching at a different spot and we're using a fake instead of a mock the second technique is to apply dependency injection so for two and three we're gonna attack this this Redis mark so this is where our test is what we want to do is change our feed class to take a collaborator and we're going to build a fake reddit connection substitute that in and then instead of asserting on a side effect we're going to assert on the state of fig Redis so what that code looks like is this this is so there's where we starting out with we're still passing in the Redis host and the change we want to make is to just inject the Redis connection it's pretty straightforward you have to change the test like this so we still have to construct a connection and fake Redis is a library that is basically an in process Redis server that has the same API so we construct the fake connection inject it and then the assertion changes to where I'm now popping data off fake Redis instead of checking the calls that happen to figure out us for topic our tactic is to inject the collaborator and really the Redis connection is not the actual collaborator it's kind of an implementation detail so it's not a big leap to realize that you should just be injecting some function that acts like a data sink so it's a really straightforward change there the run method and the feed class just changes like this you use the sink instead of the Redis connection the other thing about this class is that it's now completely decoupled from Redis it has no knowledge of any particular data store that it's sending these URLs to and the test changes like this a mock Redis is gone we just have an array and we just used receive dot append as a sync and then we're just making an assertion on the results that got sense and then we do have to change the main function a little bit to create a real Redis connection and then inject it into the feed and run it so you do need to add a few lines of code there and then the last tactic is to go functional so somebody who is a functional programmer might say your real problem is that all these all your functions have side effects if you just had pure functions you wouldn't have all these problems and so from that standpoint I took all that code and kind of refactored it into that shape so you just have this feed function but you can truck constructs this session and then on the second line it there's a function that constructs the initial request from your query string and sends it to get the first page of results the third line it takes that first page of results and then constructs the entire set of page requests it needs to get all the URLs and then sends that using this session to get all the pages back then there's some munging or parsing to get the web URLs and then you just push all those URLs out to Redis and this is what all that code looks like to Nantes to read but it there's no IO here it's just all transformations so now there's some anti patterns which I think I've observed so this is going to get a little bit more speculative and I'd be curious if anybody has has noticed these kinds of things happening as well alright first pattern is something I called bootleg TDD and that name comes from a friend of mine who follows this Instagram feed of bootleg toys and so show me things like this where you get Emperor def serious or Toby one and then my favorite one is Dennis and so what I mean by bootleg is something that's sort of superficially like the real thing but something is kind of essentially off so what that might look like with TDD is you someone who's aiming for a hundred percent test isolation a hundred percent coverage because you got to be perfect you test maybe it's us first maybe you test lasts maybe just whatever and you're not refactoring and you're doing some kind of procedural decomposition or top-down design instead of object-oriented programming and case you're not familiar with out basically and procedural decomposition you just take a function at a very high level and you break it down into two smaller subproblems take that and break it down into two smaller subproblems and so on and so your functions get more and more detailed as you do this break down so what that might look like is if you got this program P which is a high level abstraction and break it into two things a and B you decompose those into C D and E and then finally you're done you hit the database and it's it's time to test and because you want 100% coverage and isolation you say I'm going to test P and mock out a and B same thing with envy you mock out C D and E and then you test C Denis but now you hit the database and what do you do so maybe you think I should mock the DB connection or mock the query language and that's not not the greatest thing in the world because it makes your test tied to some very low level implementation details so I've ended up in scenarios where I've had a number of tests break just because whitespace and a sequel query changed and so if you go back to that Freeman in price book their advice on this kind of thing is actually don't mock code you can't change and don't mock code you can't own right because mocking is supposed to be an exploratory design tool and their advice would be to just create a database adapter and then mock that instead of trying to mock the DB connection or the query language there's another pattern related that I call I think in version walk and so if this is where I could example was as we built this up we built it from high level to level of abstractions so the dependencies go from high level to low level then you add in all your tests and so the issues I kind of noticed with this or that because somebody was doing top-down design there's no understanding a concept of dependency inversion and because there's a lot of patching and over mocking it tends to lock in that structure and so I kind of have this feeling that people would get into the habit of patching it kind of creates this obstacle for understanding dependency inversion principle and things like inversion of control and in case you're not familiar with dependency inversion we saw a very simple example when we did this dependency injection so here we injected a fake and the real app we conducted a DV and then you end up with this situation that looks like this where a total value is highly configurable and has no dependencies on implementation details so if I draw some lines around that what you'll see is that all this stuff in the middle or the core is your valuable code and all the implementation details are on the outside and there's no dependencies from the inside to the outside so total value doesn't care which database it's using it doesn't care whether the actual out is a web web app or it's a CLI or a GUI and so sometimes you'll see that referred to as clean architecture or onion architecture the other name that goes by is ports and adapters which I think should be obvious why it's called that from the picture sometimes that's also called hexagonal and the difference with this is it's just organizing the things on the outside in two different groups of adapters so if you ever see these buzzwords turnout and or these like really cryptic diagrams talking about clean and onion architectures and hexagonal you know about a 90% of what you need to know to understand what's going on there there's another pattern which I am The Blob what that is is you have some program that connects to a database so you work on it and work on I work on it and then a week later you're done and I think this one is a favorite of data scientists and it has to do with I think it's common among people who are programming but they're not in the role of software engineers so at this point you know how do you test this with this database it's kind of a little bit too late to unit test so you kind of just patch tactically or extreme tackle patching and you kind of figure out whatever and then eventually it passes and okay so the issues with this kind of thing is like not really sure what kind of test is it's not a unit tests maybe it's some sort of regression test who knows and there's also this kind of split mindset I have about this which said on one level it's it is really a provided pragmatic way of using patching and logging but on the other hand maybe it's just enabling bad habits and I think it could go both ways this one is going to get really speculative I'd be curious if anybody has actually ever seen this patches as cross cuts there's no pictures here there's just this argument that a test should ideally test a single behavior and a patch is a violation of some encapsulation boundary so a test with a lot of patches is is have a typo in there a test with a lot of patches is violating multiple encapsulation about reefs so my hypothesis around that is if you've got a test case with a lot of patches that represents a problem with cohesion and coupling so maybe your requirements changed and your package structure or your module structure is no longer adequate for your application so you might need to think about changing that or maybe it's it's a sign of a cross-cutting sir concern which was not properly captured in your package design okay so we're almost at the end I just want to share some of my opinions should always be refactoring in your test that will help you prevent you from getting into marquel consider using other test doubles besides mark or think about using some of the other features of mark that will let you configure it with these other behaviors patching should be rare my opinion is that it's the last thing you should be reaching for whenever you have a problem with testing and the mocks if you choose the use them should target roles and not objects make sure you're mocking the red abstractions and remember that they're not a tool there are never intended just as a tool for test isolation so I also want to give thanks to Brian Arkin and Harry Percival we were nice enough to answer my emails and give me feedback on my slides so Brian's book is a really good book on pi test if you're not familiar with that and then Harry's book is hands-on sort of a hands-on tutorial on doing TDD with Python and Django and I finally got some resources here there's multiple opinions on these things often it's just a question of what style you want to use and how you want to mix and match these things so there's some debates and counter opinions and other resources that you can look up so that's the end of my talk and I think we have time for questions [Applause] thanks admin so we have time for one two questions and the microphones are over there I think hello can you hear me oh great so since nobody's asking questions I thought I may give you the pleasure fakes versus mocks like when I use mocks I kind of assumed that the code like the mock code itself is tested and working whereas if I have to write my own fake like who tests that right it's essentially wrote some code yeah and I'm sorry I can't hear ya oh you cannot yeah fakes against mocks that's the question yeah and like if I write my own fake who does that right is a new set of code I have to maintain whereas if I used mock I'm using a library who somebody else wrote and tested so it is working great like do you see a problem there or not sometimes it's a question of a judgment call I personally find for me using a fake is less code to maintain and the the mark then you avoid the problems with over mocking and getting stuck on implementation details when you use a mock you typically end up having to do also do a stub and do a number a number of other things that just create technical debt but you know if you can make it work for you then I think that's fine it's just a question of which style do you want to use the function that takes several inputs and then mentally it does it simple to call one place gather information call another place and call the third place and merge them and return to so in that case like I have several inputs and then I have three dependency injection kinds of make the function or too big and yeah so that that objection to dependency injection comes up I think somewhat frequently and the question I would have is does your top level function really depend on those three data sources or is there some hierarchy of dependencies and so the creator of angularjs actually has a lot of blog posts on this idea where he talks about dependency injection and so on so I'd go look at look at those those posts if you can find them thanks again applause [Applause]
Info
Channel: PyCon 2019
Views: 7,239
Rating: undefined out of 5
Keywords: Edwin Jung, pycon, python, coding, tutorial
Id: Ldlz4V-UCFw
Channel Id: undefined
Length: 47min 14sec (2834 seconds)
Published: Sun May 05 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.