Live data from Hacker News

Ask HN: Best Way to Mock APIs in 2020?

news.ycombinator.com

41–50 of 63 posts

Re: Ask HN: Best Way to Mock APIs in 2020?

#41
post #12

Can someone explain to me what this is all about? Shouldn't you hide all your API calls behind an interface, and then mock that interface? Dependency inversion principle, depend upon abstractions and all that.

Some reasons not do to that:

- Now it's harder to navigate my codebase because I introduced an extra layer of indirection everywhere only for the sake of testing.

- If there is some difference between how the actual protocol client and actual upstream behave and how my fake interface behaves in test, my tests will be wrong, and I will find out when I push to prod. If my tests exercised the actual code that speaks the actual protocol to a fake upstream, I may have caught the issue in the tests.

- If I ever want to replace the process entirely with a completely different one, I must now throw away my tests. If my tests tested the end-to-end behavior of the system, I would be able to keep my tests.

Re: Ask HN: Best Way to Mock APIs in 2020?

#43
Use swagger-openAPI3 and generate a spec. You can then use the spec to spin up clients or import to a API management tool and produce mock data, with support for authentication and more. I recommend using swashbuckle (for .netCore) if you already have the code for your API, it allows you to quickly produce spec from code.

Re: Ask HN: Best Way to Mock APIs in 2020?

#44
post #12

Can someone explain to me what this is all about? Shouldn't you hide all your API calls behind an interface, and then mock that interface? Dependency inversion principle, depend upon abstractions and all that.

Definitely you should do that, but it's still useful to have automated API tests too. That way you can upgrade client libraries risk free (and even automate these upgrades with tools like https://dependabot.com/). If your tests are green then you're good.

Re: Ask HN: Best Way to Mock APIs in 2020?

#45
post #39
post #12

Can someone explain to me what this is all about? Shouldn't you hide all your API calls behind an interface, and then mock that interface? Dependency inversion principle, depend upon abstractions and all that.

I've gone through this process a few times: 1) Join a project and fume about how they didn't write nice, clean, "testable" code. 2) Build some sort of integration testing framework that also mocks out REST API calls relatively cheaply (e.g. using recording/playback against a live system). 3) Realize that I can now refactor the code such that it is nice, clean and more easily "unit testable". 4) Realize that with an e…

> it occurred to me that it would actually be kind of great to write tests where the entire implementation including the language itself could be swapped out without really changing the tests.

I think this basically already exists with "Cucumber" and behavior-driven development. The test definition is specified in a natural-language-looking DSL which supports a number of underlying languages. When you swapped out the system you would have to implement the step definitions in the new language, but the tests would remain valid.

Re: Ask HN: Best Way to Mock APIs in 2020?

#46
For a side project? I think that makes a difference here.

What I’ve been doing lately, in my own time outside of work, is setting up a postgres DB, pointing postgraphile to it, then I have the API out of the way.

From there, if I’m consuming that API in a statically-typed language, I’ll look at generating the models I need from the graphql schema with quicktype.

That process is usually quick enough that there’s no reason to mock.

I suppose if I was doing UI first, I would just have the repository layer that’s abstracting my calls to whatever just have a function that returns a dumb static object in the shape I expect.

Re: Ask HN: Best Way to Mock APIs in 2020?

#48
post #12

Can someone explain to me what this is all about? Shouldn't you hide all your API calls behind an interface, and then mock that interface? Dependency inversion principle, depend upon abstractions and all that.

Some reasons not do to that: - Now it's harder to navigate my codebase because I introduced an extra layer of indirection everywhere only for the sake of testing. - If there is some difference between how the actual protocol client and actual upstream behave and how my fake interface behaves in test, my tests will be wrong, and I will find out when I push to prod. If my tests exercised the actual code that speaks the…

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!

Re: Ask HN: Best Way to Mock APIs in 2020?

#49
post #48

Earlier quoted context omitted.

Some reasons not do to that: - Now it's harder to navigate my codebase because I introduced an extra layer of indirection everywhere only for the sake of testing. - If there is some difference between how the actual protocol client and actual upstream behave and how my fake interface behaves in test, my tests will be wrong, and I will find out when I push to prod. If my tests exercised the actual code that speaks the…

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 o…

All 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.
Post reply on HN