Mocks/stubs definitely have a smell to them, but especially if you want to do more than just unit tests can be necessary. I've found that setting up the mainline architecture so that components that are allowed to be mocked have a single access path in the code makes it easy to mock at a level low enough that the only thing being mocked is that component and then preemptively building out those mocks into the test framework works decently well. For me, 3rd party services are usually fine to mock, but things like DBs and redis are usually not. I'd rather spend the time to make a test container the devs can run locally so that they can't skip over checks/constraints and the integrations with services/components we have full control over.
That way you can tell at a glance of the test file change just how bad it is. Seeing new raw mocks (eg sinon in the test file at all) instead of the existing mocks is an instant no, and seeing an existing mock getting added requires at least investigation for necessity.
That way you can tell at a glance of the test file change just how bad it is. Seeing new raw mocks (eg sinon in the test file at all) instead of the existing mocks is an instant no, and seeing an existing mock getting added requires at least investigation for necessity.