Unit tests should be isolated, automated, fast and repeatable.
A “Unit” can be a function, a class, a module… There’s no one definition.
In DDD this can only be applied to Domain and Application layers
Integration tests are for infrastructure/external elements.
They should be paired with Contract Testing to ensure the test doubles you’re using are up-to-date with the real implementations.
Acceptance tests check entire flows of vertical slices of your software.
E2E tests check the entire system, including infrastructure such as Load Balancers, Databases, Caches, etc…
The element that is being tested.
You may encounter instances of code which call methods from objects or places you can’t easily mock or remove, and the original code must remain as-is functionally speaking. In that case, implement seams. Great source
These seams use 2 concepts:
They only use basic code refactoring such as
const user: User = LoggedUser.getInstance()
// Becomes
const user = this.getLoggedInUser()
//...
private function getLoggedInUser() {
return LoggedUser.getInstance()
}
They use overrides to rewrite those functions in tests so they stop using the dependencies