[HN Gopher] Testing Without Mocks: A Pattern Language (2018)
___________________________________________________________________
Testing Without Mocks: A Pattern Language (2018)
Author : etamponi
Score : 42 points
Date : 2022-03-05 09:26 UTC (13 hours ago)
(HTM) web link (www.jamesshore.com)
(TXT) w3m dump (www.jamesshore.com)
| loevborg wrote:
| Enjoyed this much more than I thought I would
|
| * Shows (almost) real-world examples to demonstrate the patterns
|
| * Uses JavaScript, which is notoriously hard to test because of
| complex UI frameworks and difficult-to-mock APIs
|
| * Set of patterns that refer to one another, providing mutual
| support
|
| Would love to read more--any other resource along similar lines
| appreciated
| omegalulw wrote:
| I found this to have many questionable claims for example:
|
| > Ensure that all Logic classes can be constructed without
| providing any parameters (and without using a DI framework). In
| practice, this means that most objects instantiate their
| dependencies in their constructor by default, although they may
| also accept them as optional parameters.
|
| When you do the latter, it kind of defeats the purpose of
| dependency injection and what you are testing won't be what you
| use in prod. And when you don't do this, you have to set up
| dependencies properly - at that point it's almost becomes an
| integration test. IMO the right thing here is to mock
| dependencies in unit tests so you can properly test the class
| in question.
|
| Fundamentally, it seems like the author hasn't worked on or
| considered complex distributed systems where stuff like
| dependency management, sequencing (back and forth
| interactions), etc really matter - you can't test those
| properly in unit tests, you need integration tests.
|
| Unit tests and integration tests complement each other, you
| can't reasonably test and update complex systems without both.
| loevborg wrote:
| I found that James has recorded a series of 22 TDD sessions
| that demonstrate the techniques outlined in the blog post in
| JS: https://www.youtube.com/watch?v=nlGSDUuK7C4&list=PLD-
| LK0HSm0...
| karlmdavis wrote:
| I'm really not clear what's going on with the null
| implementations... aren't those just very boring mocks?
| bcbrown wrote:
| This is almost exactly my approach to testing. I'm going to have
| to save this for sharing with teammates.
| tyingq wrote:
| _" Test-specific production code. Some code needed for the tests
| is written as tested production code, particularly for
| infrastructure classes. It requires extra time to write and adds
| noise to class APIs."_
|
| I don't see this much in real world code. Is there a space/niche
| that does this extensively? Does it raise a bunch of arguments
| about anti-patterns, etc?
| ravenstine wrote:
| I've seen it (and, ahem, have written it...), but it's a rare
| sort of antipattern that I think mostly happens with
| inexperienced developers. I haven't had to do such a thing in
| several years except when there was some weird
| framework/library limitation where I was semi-forced to write a
| little test-specific code. Test-specific production code
| usually is a crutch to work within weird situations ultimately
| caused by dogmatic adherence to object oriented principles
| where there's the potential for inaccessible state all over the
| place; if something is getting in the way of tests that you
| only have coarse-grain control over then having `if (env ==
| "test")` acting as a glorified `jmp` instruction might result
| in either making something testable or at least faster to test.
| Experienced developers that are at least halfway decent, rather
| than use such a crutch, instinctively consider whether the
| situation they are in is caused by stupid design and correct
| for the issue at a higher level; if they've always managed to
| think this way (i.e. like an engineer) then it may never occur
| to them why anyone would write test-specific code other than
| perhaps feature flags.
| omegalulw wrote:
| It's not always an antipattern. Another example would be a
| public API that exposes more state/info than it's users need,
| just for better tests. It's still kind of not the best
| practice, I will concede, since almost always you want to
| focus on testing the contract, but sometimes, exposing some
| extremely critical state info is ok to improve tests.
| bluGill wrote:
| It is a lot eaiser to make an interface and throw a mocking
| framework at it. I've been thinking of similar ideas for a
| while, but implementing them is hard so I never tried it.
| geewee wrote:
| I think it depends on where you draw the line. In C# it's very
| common to use interfaces even though you only ever expect to
| have a single class of the given type, just so you can stub it
| out in tests.
|
| It's unfortunate, but some languages require you to do at least
| some re-architecting so it's easy to test your code.
| mosdl wrote:
| Interfaces have other advantages as well, that is an added
| benefit.
|
| Implementing a No Op version of an interface for tests or a
| simple version that uses a map instead of db calles has a lot
| of benefits.
| BurningFrog wrote:
| WIthout reading the article, I'm on the "testability is a
| first class design criteria".
|
| Ease of testing should absolutely affect all your production
| code design choices.
|
| That said, there are terrible ways to do that, as always.
| ed-209 wrote:
| Spoiler - expososing test data from the implementation:
| https://github.com/jamesshore/testing-without-mocks-example/...
___________________________________________________________________
(page generated 2022-03-05 23:02 UTC)