4 ms·
I Mock Your Mocks
- adamkl 3y agoRelated: https://www.destroyallsoftware.com/talks/boundaries https://www.destroyallsoftware.com/talks/boundaries Also related: https://www.manning.com/books/grokking-simplicity https://www.manning.com/books/grokking-simplicity
- mvdtnz 3y agoThe author fails to justify why he "hates mocks" except a hand-waving justification of "they don't test production code". Well, they do, other than the parts that are mocked. They "don't test production code" in the same way that his unit test doesn't test production code because it only touches a fraction of the real code. I don't disagree with his decomposition, it's correct. I also agree with his approach to unit and integration testing to touch the appropriate layers. It's just his knee-jerk and unjustified hatred of mocks I'm objecting to.
- pavel_lishin 3y agoFor all the hatred of mocks, it seemed strange that the article spent so little time actually talking about them.
- sfn42 3y agoYeah. I completely agree with the part about separating db stuff and logic (it's a huge pet peeve of mine and almost nobody at work does anything like that), but I think mocks do have a place. I also think it's best to make sure the majority of our code doesn't require mocks to test. But very few people do that either even if it's fairly simple. I am fairly fresh with my two years of professional experience and I've spent a lot of energy worrying about whether there's something wrong with me that makes me want to refactor most of the code I read. I'm starting to lean towards the conclusion that it's not my fault, it's just that most devs write shitty code. And I don't think that's javas fault.
- codethief 3y agoYeah, there are so many reasons not to like mocks and he picked… that one?
- manvillej 3y agohonestly, with mocks and good type checking, I don't see why it wouldn't be valid testing
- GauntletWizard 3y agoHow will you ever achieve 100% code coverage if you don't have giant monofunctions?
- kevincox 3y agoOne tangential complaint: func validateUser(user User) error This is a bad way to validate data. It generally means that any new data added to this type won't be validated by default. It isn't too bad because it is a typed native data structure (must worse in things like JS where extra fields can slip in from the JSON) but it is better security practice to parse the data rather than just looking at it. So it would look something like this func validateUser(user User) (error, User) Then the function carefully extracts and validates the input before copying it to the output. Anything that it doesn't know about doesn't get copied. This can be thought of as "whitelist validation" rather than "blacklist validation". Parse, don't validate.
- dack 3y agoif you're going to "parse, don't validate" then the signature should probably be func validateUser(user UnvalidatedUser) (error, User) this way, you can't accidentally forget to validate your user before using it in the rest of your code
- kamray23 3y agoIf we're going that route, just forbid making User objects which are not valid. Hide the fields, force the instances to be immutable, validate in the constructor, problem solved. Does not work in things with duck typing or anything remotely resembling the two most used programming languages in new projects in the industry. But for traditional statically typed languages, it's a good solution. Now a function taking in a user is literally incapable of ever taking in an invalid user, assuming your tests for the class are good and pass.
- codethief 3y agoI have always liked this approach and, recently, I came across a term for it: "type tightness"[0]. I gotta say, it really stuck with me. [0]: https://www.ecorax.net/tightness/ https://www.ecorax.net/tightness/
- turboponyy 3y ago
- kebsup 3y agoI've found the best to test everything from the http handler to database in one test. Unless you want to write 5 different tests for each endpoint. In one project we've run the tests against in-memory db and production was postgres. Of course there was a bug caused by different SQL implementations. Other time, we've tested only the the service layer (the fiddling part worth testing), skipping the spring boot controller. Of course there was a bug caused by bad annotations at the controller layer.