How should integration testing be structured in Node.js using Jest?

I’m planning to set up integration testing in JS with Jest, and I’m looking for guidance on best practices.

I understand that integration tests interact with real databases and third-party services, but how should I structure them?

Should they look different from unit tests in terms of file naming (e.g., .spec.ts vs something else)? Should I isolate them in a specific directory like /tests/integration/?

And when it comes to mocking, should I avoid all stubs/mocks entirely, or is it acceptable to mock external services selectively?

Curious how others approach full-stack or backend integration testing in their Node.js projects.

In my team, we keep integration tests clearly separated in a /tests/integration/ folder to avoid mixing them with unit tests.

We suffix them with .int.test.js or .int.spec.ts so it’s easy to filter them out during CI runs.

One thing that helped was spinning up a real test DB (using Docker) and seeding it before each test suite.

We avoid mocking unless we’re hitting external services like Stripe or Twilio, those we fake out with minimal stubs to keep tests fast and isolated.

Integration tests can still be lean, you just need clear setup and teardown logic.

For us, the key was to treat integration tests like mini production runs. We put them in /__tests__/integration/, and they run against real instances of our services using environment variables.

No mocks at all, we want to verify that our API, DB, and auth layers play nicely together.

I use supertest to hit the express endpoints directly and usually write full flows like “register user → login → fetch profile.

That said, we stub third-party APIs at the network level using tools like nock or msw-node to avoid calling real external systems.

I used to lump integration tests in with unit tests until it got messy. Now I follow a structure like /tests/unit/ and /tests/integration/, and prefix files with integration. to be crystal clear.

Integration tests spin up the whole app using something like app.listen(...) and use test DB containers with testcontainers-node. For external APIs, I stub them, but never anything internal.

That line helps me avoid false positives while keeping tests realistic. And yeah, naming and directory structure matters more than I initially thought. Keeps the team aligned.