Safeguard
Security

aws-sdk-mock: Secure Testing and Migration to SDK v3

aws-sdk-mock targets AWS SDK v2, which is now in maintenance mode. Here is how it works, where the security risk lives, and how to migrate to aws-sdk-client-mock for v3.

Yukti Singhal
Platform Engineer
5 min read

aws-sdk-mock is a test-only library for stubbing AWS calls, and the most important thing to know about it in 2025 is that it targets AWS SDK for JavaScript v2 — if your project has moved to SDK v3, you should be using aws-sdk-client-mock instead. The aws sdk mock pattern is everywhere in Node.js test suites because hitting real AWS services in unit tests is slow, flaky, and occasionally expensive. But the tooling split between v2 and v3 trips up a lot of teams, and dev dependencies like this one carry supply-chain risk that people tend to ignore precisely because "it's only used in tests."

What aws-sdk-mock does

aws-sdk-mock intercepts calls made through the AWS SDK v2 client so your tests can return canned responses instead of reaching AWS. You mock a service method, assert your code handled the response, and restore the original afterward:

const AWS = require("aws-sdk");
const AWSMock = require("aws-sdk-mock");

AWSMock.setSDKInstance(AWS);
AWSMock.mock("S3", "getObject", (params, callback) => {
  callback(null, { Body: Buffer.from("hello") });
});

// ... exercise the code under test ...

AWSMock.restore("S3");

It works by wrapping the SDK's service prototypes, which is why it is tightly coupled to the v2 SDK's shape. That coupling is the root of the migration story.

Why the v2 vs v3 distinction matters

AWS SDK for JavaScript v3 is a ground-up rewrite. It is modular — you install @aws-sdk/client-s3 rather than one giant aws-sdk package — and it is written in TypeScript with a command-based API. Instead of s3.getObject(params, cb), you construct a command and send it:

const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
const client = new S3Client({});
await client.send(new GetObjectCommand({ Bucket: "b", Key: "k" }));

Because the client internals are completely different, aws-sdk-mock cannot intercept v3 commands. The AWS SDK team's own recommendation is to use aws-sdk-client-mock (published as npm aws-sdk-client-mock) for mocking v3. It hooks the send method and lets you match on command type:

const { mockClient } = require("aws-sdk-client-mock");
const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");

const s3Mock = mockClient(S3Client);
s3Mock.on(GetObjectCommand).resolves({ Body: "hello" });

There is a companion package, aws-sdk-client-mock-jest, that adds Jest matchers like expect(s3Mock).toHaveReceivedCommandWith(...) so your assertions read naturally. If your tests import npm @aws-sdk/client-s3 or any other @aws-sdk/client-* module, that is your signal to reach for the v3 mocking stack rather than aws-sdk-mock.

The AWS SDK v2 maintenance clock

AWS moved SDK v2 into maintenance mode, meaning it receives critical fixes but no new features, and end-of-support is on the roadmap. Anchoring your tests to aws-sdk-mock keeps you tethered to that aging v2 client. When you eventually migrate production code to v3 — and you should, because that is where security and feature work happens — every test built on aws-sdk-mock needs rewriting anyway. Migrating the mocking layer as part of the SDK upgrade, rather than after, avoids a second painful pass.

The part people skip: dev dependencies are still your supply chain

The instinct to treat test tooling as low-risk is understandable and wrong. aws-sdk-mock, aws-sdk-client-mock, aws-sdk-client-mock-jest, and their transitive dependencies all execute on developer laptops and, critically, inside CI runners — the same CI runners that hold your AWS deployment credentials, npm publish tokens, and source code. A compromised dev dependency has a direct line to exactly the secrets an attacker wants.

Two attack classes matter here:

Install-time script execution. npm packages can run postinstall scripts the moment they are installed, before any test runs. A malicious version of any package in your dev tree can exfiltrate environment variables during npm install in CI. Running npm ci --ignore-scripts where possible, and pinning exact versions via package-lock.json, shrinks this window.

Typosquatting and confusion. The AWS testing ecosystem has several similarly named packages — aws-sdk-mock, aws-sdk-client-mock, mock-aws-s3, and near-misses of each. A typo in a package.json can pull an impostor. Verify the package name and its publisher on npm before adding it, and prefer packages with a clear maintenance history and repository link.

Because these dependencies live under devDependencies, some scanners deprioritize them. That is a mistake for anything that runs in CI. Software composition analysis should cover your full dependency tree, dev and production alike; our SCA overview explains why the CI-executed graph deserves the same scrutiny as the shipped one. An SCA tool such as Safeguard can flag a newly published, low-reputation version of a test dependency before it lands in a build.

Practical migration checklist

  • Audit which SDK version your production code uses. If any module imports from @aws-sdk/client-*, you are on v3 and should mock with aws-sdk-client-mock.
  • Replace AWSMock.mock(...) calls with mockClient(...).on(Command).resolves(...).
  • Add aws-sdk-client-mock-jest if you use Jest, so command assertions stay readable.
  • Pin exact versions in package-lock.json and enforce npm ci in CI for reproducible installs.
  • Include dev dependencies in your vulnerability scanning, not just production ones.

FAQ

Is aws-sdk-mock deprecated?

Not formally deprecated, but it is designed for AWS SDK v2, which itself is in maintenance mode. For AWS SDK v3 projects the AWS team recommends aws-sdk-client-mock. New projects on v3 should not adopt aws-sdk-mock at all.

What is the difference between aws-sdk-mock and aws-sdk-client-mock?

aws-sdk-mock intercepts the v2 SDK's service methods; npm aws-sdk-client-mock intercepts the v3 client's send method and matches on command classes. They are not interchangeable because the two SDK generations have fundamentally different internals.

Do test dependencies really need security scanning?

Yes. Test and build dependencies run inside CI runners that hold deployment credentials and publish tokens, so a compromised dev dependency is a direct path to your most sensitive secrets. Scan the whole tree, including devDependencies.

How do I mock a specific S3 command in v3?

Use aws-sdk-client-mock: create mockClient(S3Client), then chain .on(GetObjectCommand).resolves({ ... }). Add aws-sdk-client-mock-jest for matchers such as toHaveReceivedCommandWith when you want to assert on the exact parameters your code sent.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.