6 ms·
Mocking has a place, which is not unit testing. If you find yourself mocking a dependency in a unit test you are not unit testing any more. Those points of con
by tuxie_ 5y ago
Mocking has a place, which is not unit testing. If you find yourself mocking a dependency in a unit test you are not unit testing any more.
Those points of contact with 3rd parties should be clearly defined and encapsulated at the perimeter of your system. Mock at that level. Not when testing business logic.
- catwind7 5y agowhat does unit testing have to do with whether or not you instrument the test with fake responses? those points of contact that you're mocking out at the perimeter, that data will sometimes need to reach a particular function through a collaborator...which you may want to mock? sometimes the dependency is not a third party, but it may be code that requires a ton of setup (as mentioned in article) that's not worth the cost. it may make sense to just mock at that point to actually test the rest of the business logic in a function. I don't think i'd say "well, that's no longer a unit test!". You can argue that it's a more brittle test, sure. update: also, i'll be honest that comments like this really rub me the wrong way. This type of dogmatism around what is or isn't unit testing (which is a pretty ill-defined phrase in industry) is something that needs to stop. I think it hurts new practioners in the field who are mislead into black and white thinking.
- tuxie_ 5y agoI'm sorry, I did not intend to offend anyone obviously. Needless to say, this is just my opinion condensed in a sentence (therefore lacking a lot of context, which I should have provided). I was not aiming to define what a unit test is, more like when it stops being a unit test (which I thought it would be an easier agreement to reach than a definition of what is, but I guess I underestimated the task). My point was that if you have to mock, for example, a DB call inside your business logic, well you are writing an integration test at that point, whether or not you mock the DB out. If you design your code so that you only have those dependencies at the edge of the system then you get, in my opinion, a much cleaner design and much more testable code. Too much mocking (and/or more like mocking in the wrong places) is a code smell in my opinion.
- detaro 5y agoSo components that talk to the outside can't be unit-tested at all?
- tuxie_ 5y agoHi detaro. Good question. If all my module does is make an api call, and I mock the API, what am I testing? I would rather leave that out of the unit tests because the added value is, in my opinion, close to none if you are relying on mocked data. Now, if the module does more than just call the API then I would argue that it's breaking the single responsibility principle and would prefer to split it into a module that does only the call and another that does the rest.
- detaro 5y agoOk, then go one level in: If a component uses the "only makes an API call module", how do I unit test it? I can't let it use the module to make the API call (because the API might not be available in testing/that's an integration test/...), and I can't mock it, because using a mock would make it a not-unit test? I guess this gets at the line between mocks and stubs, but I never found that all that convincing.
- tuxie_ 5y agoYes, you just don't unit test it, because if you mock out the only dependency it has you are left with nothing. So you are not unit testing anything anyway. You know what I mean? That code can (and should) be tested, through an integration test.
- deleted 5y ago[deleted]
- catwind7 5y agoby claiming when something stops being a unit test, you have to define what a unit test is. Now, I do think there is a good, reasonable definition of a unit test and it's looser than yours. A single function that reaches out for an API call via another function and does N other steps of compute that has the API call mocked is still a unit test. can it be a smell? maybe, that depends. Does it break your idea of single responsibility? maybe. Is it an integration test? not ... really because the test is primarily designed to verify the behavior of the rules of the function and not its interaction with a third party system. so while you can argue that mocking is a smell in that context, that doesn't change the fact that it's still a unit test! all that said, one can still make a case that the fundamental unit of work for a given context is not really a function, and so testing functions are actually integration tests! so I'll also grant that these definitions can be very context sensitive..
- bluepizza 5y agoWhy?
- ipaddr 5y agoBecause he has reached a conclusion. Anything further can be safely ignored if it doesn't fit that conclusion. Never let someone tell you what unit tests are.
- tuxie_ 5y agoHi, I don't really understand who do you refer to when you say that "anything further can be safely ignored". By me? What exactly can be ignored? Sorry, I would like to answer your comment since it seems that it upset you, and nothing was further from my intention. But I honestly don't understand what you mean.
- tuxie_ 5y agoHey bluepizza. As I wrote in response to another comment, I think that too much mocking (and/or mocking in the wrong places) is a code smell. I was not aiming to define what a unit test is, more like when it stops being a unit test, and I think that if you have to mock, for example, a DB call inside your business logic, well you are writing an integration test at that point, whether or not you mock the DB out. If you design your code so that you only have those dependencies at the edge of the system then you get, in my opinion, a much cleaner design and much more testable code.
- bluepizza 5y agoBut if you include a real DB on your business logic testing, that's not unit testing anymore, is it,
- tuxie_ 5y agoExactly. It may sound ridiculous but it happens all the time. You dig into the "unit tests" of the app and you find mocks for a db call, or an API call, or the system's date, or environment variables that some other part of the system will break if they are not defined (or all of the above). That's what I mean, these are all code smells that the code is highly coupled.
- deleted 5y ago[deleted]
- aliasEli 5y agoThe term "unit test" can mean a lot of things (which is very unfortunate). Does it mean: - A test of some of the requirements that can be done very fast. (That's my preferred form when involves a large part of the code) - A test of a small piece of code that makes a lot of assumptions about other code by mocking it. (Not a good idea, but it might work in your organization) P.S. I did not read your post, while I was writing mine.
- 8note 5y agosomething else calls that encapsulation. So you can also mock your encapsulation in the next layer, than that one in the next, etc