4 ms·
I think mocks in unit tests are a code smell, that indicates that the business logic has not been correctly isolated from the rest of the code, or that the code
by kraftman 7y ago
I think mocks in unit tests are a code smell, that indicates that the business logic has not been correctly isolated from the rest of the code, or that the code shouldn't be unit tested at all, and should instead be component/integration tested.
- closeparen 7y agoMost architectural guidance encourages separation of concerns into layers (handler, controller, gateway, etc). Each layer consumes the next. You will be hard pressed to unit test one layer without injecting a mock of the layer below. When the layer is essentially pro forma and has no logic of its own, this is excruciating, but the line coverage number rules all.
- kraftman 7y agoYeah, I think this separation of concern misses a step. Let's say you have controller -> Business logic layer -> Data access layer. The controller takes in some input, validates it, passes it to the business logic layer. The business logic layer retrieves some data from the DAL, does some logic, maybe writes data back to the DAL, and passes the data back up to the controller. The problem is that the business logic layer is usually doing two things at the same time, in the same function: the 'plumbing' (calling other things and passing data round), and the actual business logic. When you try and define a boundary around the code, it gets messy, because what you want to test, the business logic, is mixed in with the plumbing so you have to use either dependency injection or mocking to force a boundary. This makes your tests more brittle as changes in things you don't want to test (your dependencies) affect your tests. If you pull out the business logic into its own modules, and instead have a function that orchestrates the business logic (i.e. tell the database what data you want, tell the business logic functions to perform an operation on the data), you end up with a nice clean boundary around your business logic, which can be unit tested easily without mocks. You then test the 'plumbing' part by using a component test that checks that the inputs and outputs of the component as a whole (business logic + plumbing + data access) are correct.
- closeparen 7y agoI think what you’re describing is what we would call a controller, and management / senior ICs would still demand 90% line coverage by unit tests.