Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I keep hearing this but I don't quite understand what the alternative is? I get that maybe introducing interfaces within your own business domain CAN be overused but certainly any external depedency should be fronted by an interface so the rest of the code can be tested without spinning up test http servers, database containers etc. all over the place. It just feels like a really lightweight, simnple thing to have an interface for some API that you are calling. It also means you are less depedent on the concrete implementation of the API and don't leak types and behaviour from systems you don't control into your codebase


Instead of pushing the external, side-effecting thing down the stack, I put it up the stack and call the logic that generates the data for it from there. Now I don't need to mock an interface, I just need to test data in/out.

If you do this consistently, then you have much of the side effecting code residing next to each other per process/input handler etc.

It's not always feasible or the right thing. But it's a good default way of structuring code and makes testing much more straight forward. And it makes more clear "at a glance" what happens because you can reason more locally about the side effecting parts.

> It also means you are less depedent on the concrete implementation of the API and don't leak types and behaviour from systems you don't control into your codebase

You are always dependent on that. Whether you hide it down the stack or lift it up, you still need to put your data into a specific shape, do the same essential checks etc.


> Instead of pushing the external, side-effecting thing down the stack, I put it up the stack and call the logic that generates the data for it from there.

I've never seen Go code that does anything else. That's not to say it doesn't exist, but it's seemingly not the norm amongst Go developers (probably exactly for the reasons you describe). That doesn't address what the parent is talking about, though. You have the exact same problem spoken of no matter where in the stack you put it.


This is a situation where I enjoy coding in TypeScript. You don’t need to front with interfaces, you just mock objects that map 1:1 with the expected API. So you write your code targeting the standard Fetch API then just pass in a mock when testing.


+1 to this. Especially with go, most of the (non-integration) tests I end up writing are behaviour driven tests. I'm not really sure how one can write these sort of tests without interfaces and mocks.


One could use build tags to provide alternative implementations over a concrete type, I suppose.

But like with everything in life, there is no right solution. Just different tradeoffs. If interfaces best align with the trades you are willing to make, go for it.


To be honest, if I were writing software in Go I would just test it end-to-end.

If the software's logic is too complex and fiddly to lend itself to straightforward end-to-end testing (i.e. enterprise software), I just wouldn't write it in Go. I'd choose a higher level language like Python or Java where mocking (and other kinds of dynamism) are straightforward and require no boilerplate.


Could be structural duck typing, like typescript does. Or just include some other monkey patch mechanism specific for tests.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: