When you're running integration tests, you often face the challenge of balancing between using mocks and actual dependencies. Mocks can make your tests faster and more reliable, but they might hide issues that only show up when using real systems, such as APIs or databases. Some tools like Keploy, WireMock, and Hoverfly help to either simulate or record real interactions. It can be tough to decide how much to mock versus how much to rely on real dependencies. What's your approach for managing this trade-off in your projects?
8 Answers
I love using TestContainers! It can set up a PostgreSQL database in a container dynamically, which pushes me towards more realistic integration tests without needing full infrastructure.
Personally, I find fakes to be a great option. They’re simple implementations of the same interface and allow for end-to-end testing without losing the benefits of mocking. It’s valuable for partial-integration tests, which often don’t get enough attention.
While I'd love to not mock anything, sometimes it's unavoidable. I've worked on systems without dedicated test environments, and if we need integration tests ahead of production, we might have to call live APIs or resort to mocks.
Mocks can feel like a cheat. I think dynamic tests give a more honest view of how systems really interact.
The goal of integration tests is to check how different parts of your system work together, so I believe you shouldn't really mock anything. In contrast, for unit tests, you're testing isolated units, where mocking is necessary to control all interactions they have. You just have to trust your instincts on how much mocking to do in between these two levels.
Right on point! Just remember, integration tests should ideally run in a test environment to avoid issues.
Whenever possible, I prefer using actual dependencies. It encourages you to create easy setup and teardown procedures for your test environments. I've seen too many tests pass using mocks only to fail in reality.
I typically mock the database but keep everything else real. Rest calls, however, I prefer to mock.
I usually mock for unit tests since the goal there is to ensure that, assuming the API behaves as expected, my code is working correctly. For instance, I can mock my database to verify that the right queries are being sent and handled well. However, for integration tests, I don’t mock essential parts because the main idea is to test how the components work together. For example, I've got an app that communicates with Azure Storage; I mock those calls in unit tests, but I have a dedicated integration test using a testing account we maintain.
Just to clarify what you said: while you don't mock essential parts for integration, you could still mock things that aren't key to the integration test. For instance, if you're testing a database query and your app has a Redis cache linked, it’s smart to mock the Redis calls to focus on the database interaction.
Exactly! Also, you should never mock your database since migrations can throw off your assumptions and lead to more problems down the line.

You nailed it! It's almost a strict separation; you're rarely in a gray area. It's usually safer to have your unit tests handle the lower methods.