3 ms·
What I find works well is to use dependency inversion to mock things out within your code, but mock out the transport layer. I.e: If you have a "stack" like th
by borland 6y ago
What I find works well is to use dependency inversion to mock things out within your code, but mock out the transport layer.
I.e: If you have a "stack" like this:
- Application
- MainService
- ApiService
- HttpClient
What you might think of doing is replacing the ApiService with a mock, such that you can test your MainService's interactions with it.
You can do that, sure, and it's useful - but as you rightly point out now you can't find any bugs in your ApiService.
Instead, mock out the HttpClient (or if it's not Http, mock out the Socket). Typically because these kinds of things are at the bottom of the stack, they have very simple interfaces and are really easy to mock, and because the interfaces are so simple the mocks don't introduce much - if any - damage to the rest of your code around them.
There are significant advantages to doing it this way too, over using an external mocked API.
- Way faster
- More reliable
- Single codebase (if the mock API is some external NodeJS thing now you have to wrangle that too)
- You have perfect control over timing. For example, if you have a bug in your ApiService which happens when two packets get interleaved in exactly the wrong way, you can reproduce this easily. If you had a real HttpClient talking to an external process it's nigh impossible.
Good luck!
- paledot 6y agoAll good points, but you missed the most important part: in any mature programming language, you're not implementing the HttpClient yourself: it's a library, package, bundle, whatever. Which means that when you mock that you're not missing out on testing any code that you wrote, and the project that maintains your HttpClient (hopefully) has their own community-maintained test suite.
- berkes 6y agoHave a look at VCR. It was developed for Ruby, and does exactly that: mock out the actual HTTP part of your HTTPClient. It does this by first making the actual request and then storing that record in a plain YAML file (which you can alternatively generate yourself, by hand or from an openapi spec) Have a look at "Ports in Other Languages" in their README to find the VCR port for your language, framework or stack.