News for hackers. Stuff that matters.
Re:Ask HN: Concepts that clicked only years after you first ... by sanderjd on Sunday January 01, 2023 @11:29AM (#34207674)
Yep, I think mocks are mostly a smell. The "functional core" of a module should be entirely or almost entirely unit testable with dependencies passed in. The glue code ("imperative shell") should be tested at a higher level - "integration" or "end to end" or whatever you want to call it - which looks at the externally observable effects of running the code (database changes or API responses or whatever) rather than the details of its execution.
Re:Ask HN: Concepts that clicked only years after you first ... by closeparen on Sunday January 01, 2023 @12:13PM (#34208222)
This is the way, but it’s tough to sell “we’re not going to unit test this part” in a professional setting where there are incentives to look more responsible than thou, directors are looking at unit test coverage reports, etc.
Re:Ask HN: Concepts that clicked only years after you first ... by sanderjd on Sunday January 01, 2023 @01:02PM (#34208820)
Yeah I have no qualms about writing mostly-BS unit tests when the existing structure of a project makes it infeasible to write good ones. When in Rome! But when I'm starting from scratch or have a chance to do refactoring, I move toward the "functional core" approach as much as possible.
Re:Ask HN: Concepts that clicked only years after you first ... by therealdrag0 on Monday January 02, 2023 @12:28PM (#34220708)
You can still get code coverage points with broader tests.

I think it’s reasonable to disavow expecting single unit tests for nearly every method on every class with mock/boilerplate/copy-paste hell. However, I would still expect “local integration” unit tests that exercise broader chunks of code and keep code coverage up.

So it should be “I don’t need to write a new unit test for this because an existing unit test calls the method that calls this method without it being mocked and you can see it’s covered in the code coverage.”

Re:Ask HN: Concepts that clicked only years after you first ... by closeparen on Monday January 02, 2023 @12:52PM (#34221094)
Code coverage in Go is on a package level. A test that exercises a handler, controller, and repository can accrue coverage for at most one of them.
Re:Ask HN: Concepts that clicked only years after you first ... by therealdrag0 on Monday January 02, 2023 @02:04PM (#34222196)
Huh. I guess I’ll add that to the list of reasons I don’t like Go.
Re:Ask HN: Concepts that clicked only years after you first ... by delecti on Sunday January 01, 2023 @02:02PM (#34209515)
How are mocks a smell if "unit testable with (possibly fake) dependencies" is okay? That's what mocks are.

Or do you mean specifically "expecting" interactions with those mocks? Because I agree that's usually not that valuable.

Re:Ask HN: Concepts that clicked only years after you first ... by Cyph0n on Sunday January 01, 2023 @02:33PM (#34209898)
Fakes are not mocks. A fake is an actual implementation of the dependency that runs in-process/in-memory. This means that, unlike with mocks, your test code does not dictate the behavior/outputs.

Ideally, service owners would write and maintain the fake to ensure that it stays in sync as changes are made to the actual service.

Re:Ask HN: Concepts that clicked only years after you first ... by sanderjd on Sunday January 01, 2023 @02:50PM (#34210095)
Basically what Cyph0n said, fakes and mocks aren't the same thing.

But it isn't quite as smelly when I see a mock (or "stub" more typically) used as an expedient way to create a fake to pass in as a dependency.

Like you said, it is asserting on the interactions with a mock that is what primarily smells bad to me. I very rarely (honestly I think maybe never) see this done in a way that isn't just rewriting the implementation of the method as expectations in the test.

Re:Ask HN: Concepts that clicked only years after you first ... by Scubabear68 on Sunday January 01, 2023 @02:10PM (#34209615)
Amen. I have been frustrated at many jobs where developers were so proud of endlessly writing mocks and spending more time on their tests than on core functionality.

Over time I have favored very basic unit tests and leaning in more on automated integration and regression tests. I know the theory of unit tests catching things earlier, I just don’t think it matters in practice.

Re:Ask HN: Concepts that clicked only years after you first ... by sanderjd on Sunday January 01, 2023 @02:55PM (#34210153)
I think in practice unit tests are both the most and least useful tests. Unit tests of code that just generates output as a function of input are the most useful, and unit tests of code that just glues together a bunch of side effects are the least useful. I like to find ways to structure things so that it is mostly comprised of the first kind of code, and has so little logic in the second kind of code that it's easy to justify not unit testing it.
Re:Ask HN: Concepts that clicked only years after you first ... by alpaca128 on Sunday January 01, 2023 @03:27PM (#34210514)
I once saw type checking presented as kind of an alternative to unit tests which doesn't rely on the assumption that developers write good tests, and I really like that viewpoint. A powerful type system can prevent many bugs, doesn't need additional test code and doesn't make any assumptions.

Of course it's not necessarily a full replacement, but it's definitely better and more time efficient than bad tests.

Re:Ask HN: Concepts that clicked only years after you first ... by sanderjd on Sunday January 01, 2023 @03:39PM (#34210607)
Yes, static analysis of types can eliminate a big class of unit tests (basically just checking pre- and post- conditions on types), which is a big part of why it's great. But most unit tests should be for logic. But that's why they aren't very useful for "glue" methods which just thread things through different dependencies - they shouldn't have much interesting logic.
Re:Ask HN: Concepts that clicked only years after you first ... by codethief on Sunday January 01, 2023 @09:26PM (#34213530)
> Of course it's not necessarily a full replacement

I'd actually say: Not in the slightest. A type system just rules out illegal input values[0] but it won't ensure that your business logic is correct.

And even that[0] is not entirely correct because, most of the time, a type system just rules out some illegal values but not all of them, because it cannot represent all possible constraints. Gary Bernhardt discussed this whole type checking vs. tests debate at length here: https://www.destroyallsoftware.com/talks/ideology