# Write Jest Unit Tests for a NestJS API

Yes. An agent writes Jest specs for NestJS services that lack them, builds each with Test.createTestingModule, runs npm test, and opens a PR.

[Run this on Rush](https://cloud.getrush.ai/run/write-jest-unit-tests/nestjs/), in a Project that has your repository.

## What the agent does

The agent reads how the API is already wired before it writes a single spec. In a NestJS app like brocoders/nestjs-boilerplate it opens `package.json` and finds `@nestjs/common` at `11.1.18`, Jest `30.3.0`, TypeScript `5.9.3`, and scripts `test` (`jest`), `test:cov` and `test:e2e`. The Jest block sets `rootDir` to `src`, `testRegex` to `.*\.spec\.ts$`, `ts-jest` as the transform, and `testEnvironment` to `node`. There is a `package-lock.json`, so installs use npm, not yarn or pnpm.

It then lists every `*.service.ts` under `src/` and looks for a matching `*.service.spec.ts`. In this boilerplate the providers are all missing unit specs: `src/auth/auth.service.ts` (email login, bcrypt compare, session hash, JWT issue), `src/users/users.service.ts` (create with salted password, pagination), `src/session/session.service.ts`, `src/mail/mail.service.ts`, `src/mailer/mailer.service.ts`, `src/home/home.service.ts` (reads `app.name` from `ConfigService`), the file upload variants under `src/files/infrastructure/uploader/`, and the social auth services (`auth-google`, `auth-apple`, `auth-facebook`). End-to-end coverage already lives under `test/` with Docker Compose files; the gap the agent fills is unit specs next to the providers.

For each chosen service it adds a `*.spec.ts` that builds the provider with `Test.createTestingModule` from `@nestjs/testing` (pinned with the Nest packages at `11.1.18`). Collaborators such as `UsersService`, `SessionService`, `MailService`, `JwtService` and `ConfigService` are provided as real instances when their dependencies are light, or as typed stubs when they touch TypeORM or Mongoose repositories. Specs exercise behaviour: `AuthService.validateLogin` rejecting a missing user or wrong provider, `HomeService.appInfo` returning the configured name, `UsersService.create` hashing a password before persist. Seed services under `src/database/seeds/` stay out of scope unless the prompt names them.

It runs `npm test` in the sandbox (and `npm run test:cov` when the prompt asks for coverage) until the new specs pass, then opens a pull request that lists each new file and which branches it covers. Production `.service.ts` files are not rewritten; only new `*.spec.ts` files land in the diff.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Write Jest unit tests for the NestJS services in this API that have no spec file, building each with Test.createTestingModule and real collaborators where practical. Run npm test and open a pull request.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request on a new branch. In a repository shaped like brocoders/nestjs-boilerplate it adds `*.service.spec.ts` files beside providers such as `auth.service.ts`, `users.service.ts` and `home.service.ts`, each importing `Test` from `@nestjs/testing` and asserting on public methods. Existing e2e Docker flows under `test/` and `docker-compose.*.test.yaml` are left alone.

The pull request description lists which services had no spec, which collaborators were real versus stubbed, and the `npm test` result from the sandbox. The session trajectory keeps the Jest output, so a reviewer can see failures the agent fixed before pushing.

Before merging, a reviewer checks that the specs do not reach a live database, that password and JWT paths use test doubles for secrets, and that the new files match the repo's `testRegex`. Once merged, `npm test` in CI picks them up with no workflow change.

## Run it on every new NestJS service without a spec

Hook your generator or pull-request bot so that when a commit adds a `*.service.ts` under `src/` with no matching `*.spec.ts`, your server sends this request with the repository in `resources`. Each gap gets its own sandbox run and a pull request that only adds the missing Jest file.

Point the API key's webhook at your server to receive `run.completed` or `run.failed`. Respect `max_concurrent` (4 by default); a Monday sweep across a large monorepo should queue starts rather than fire them all at once.

## Why run it on Rush?

NestJS unit specs need a working `Test.createTestingModule` graph and honest stubs for TypeORM or Mongoose repositories. Doing that on a laptop means installing the boilerplate's lockfile, waiting on Jest, and holding half-written specs in your tree. On Rush the agent builds that graph in its own sandbox, runs `npm test` there, and only opens the pull request when the suite is green.

You get proof, not a claim: the trajectory shows every Jest run, the pull request names which services were bare, and production providers stay untouched. The same request can fill missing specs across several Nest APIs in parallel, each reviewed before merge.

## Frequently asked questions

### Will it mock every dependency?

No. The prompt asks for real collaborators where practical. Light services like `HomeService` keep a real `ConfigService` with a test config. Repository-backed services get typed stubs for the persistence port so the spec stays a unit test, not a hidden e2e run.

### Does it replace my Docker e2e suite?

No. Files under `test/` and scripts like `test:e2e:relational:docker` stay as they are. This job only adds `*.spec.ts` files under `src/` for Jest's `testRegex`.

### What about auth and password hashing?

Specs drive `AuthService.validateLogin` and `UsersService.create` with known plaintexts and assert on thrown `UnprocessableEntityException` codes and on bcrypt hashes differing from the input. They do not print secrets into the pull request or the trajectory fields meant for operators.

### npm, yarn or pnpm?

Whatever the lockfile says. The Brocoders boilerplate ships `package-lock.json`, so the agent runs `npm test`. If your app has `pnpm-lock.yaml` or `yarn.lock`, it uses that package manager instead.
