Learn the vocabulary of a class receiving its collaborators from the outside instead of building them itself.
0 / 5 completed
1 / 5
At standup, a dev mentions a class receiving its collaborators, like a database client or a logger, as constructor arguments from the outside, rather than creating those collaborators itself internally. What is this technique called?
Dependency injection has a class receive its collaborators, such as a database client or a logger, as constructor arguments supplied from the outside, rather than the class creating those collaborators itself internally, which decouples the class from the specific concrete implementation of whatever it depends on. The singleton pattern is a related but distinct pattern about guaranteeing only one instance of a class can ever exist, which is orthogonal to how a class receives its dependencies. This externally-supplied-collaborator approach is exactly what makes it possible to swap in a different implementation, like a fake database client for testing, without changing the class's own code at all.
2 / 5
During a design review, the team has a service accept its database client as a constructor argument instead of constructing that client internally, specifically so a test can pass in a fake client instead of a real one. Which capability does this injected dependency provide?
Accepting the database client as a constructor argument provides substituting a fake collaborator for testing, since the service never hardcodes which concrete client implementation it uses internally, it only relies on whatever interface that client exposes, so a test can simply construct the service with a fake client instead of a real one, with zero changes needed to the service's own code. Having the service construct its own real database client internally instead locks it to that one specific implementation, with no way to substitute anything else without actually modifying the service's source. This substitutability is exactly the core practical benefit dependency injection provides for testing.
3 / 5
In a code review, a dev notices a class's constructor accepts a logger as an injected dependency, but deep inside one of its methods it also directly constructs its own separate database client instead of accepting that as an injected dependency too. What does this represent?
This is inconsistent dependency injection, since the internally constructed database client is locked to one specific concrete implementation with no way to substitute a fake version for testing, unlike the properly injected logger, which means any test exercising this class still has to deal with whatever the real database client actually does. A cache eviction policy is an unrelated concept about discarded cache entries. This half-injected, half-internal pattern is exactly the kind of inconsistency a reviewer needs to flag, since it undermines the very testability benefit dependency injection was adopted for in the first place.
4 / 5
An incident report shows a test suite for a service kept failing intermittently, because although the service accepted an injected logger, it also internally constructed its own real database client deep inside one method, meaning every test exercising that method actually hit a real, sometimes-flaky database instead of a controllable fake. What practice would prevent this?
Consistently injecting every collaborator the service actually relies on, including the database client alongside the already-injected logger, lets tests substitute a controllable fake for every single dependency rather than only some of them, which is exactly the fix for the intermittent test failures described in this incident. Continuing to let the service internally construct its own real database client, with only the logger properly injected, is exactly what left tests exposed to a real, sometimes-flaky database they had no way to control. This consistent, all-the-way-through injection is a standard requirement for actually getting the testability benefit dependency injection is meant to provide.
5 / 5
During a PR review, a teammate asks why the team insists on injecting every collaborator a class depends on instead of allowing some dependencies to be injected while others are constructed internally for convenience. What is the reasoning?
Any dependency still constructed internally can't be substituted for a fake version during testing, or swapped for a different implementation in a different environment, so it undermines exactly the flexibility and testability dependency injection is meant to provide, no matter how many other dependencies on that same class are properly injected. A single internally constructed collaborator is enough to leave a class partially locked to one concrete implementation, reintroducing the exact coupling problem dependency injection was adopted to remove. The tradeoff is the small extra effort of threading every dependency through the constructor consistently, rather than taking a shortcut for whichever dependency seems inconvenient to inject in the moment, which is worth it for the full testability and flexibility benefit.