Giter Site home page Giter Site logo

rehos / aws-sdk-client-mock-vitest Goto Github PK

View Code? Open in Web Editor NEW

This project forked from stschulte/aws-sdk-client-mock-vitest

0.0 0.0 0.0 399 KB

Custom vitest matcher for aws-sdk-client-mock

License: MIT License

Shell 2.12% TypeScript 96.85% JavaScript 1.02%

aws-sdk-client-mock-vitest's Introduction

AWS SDK Client Mock Vitest

CI Status Coverage Status npm version

This module adds custom matchers to verfiy calls to your AWS Client Mock. It was heavily inspired by aws-sdk-client-mock-jest.

Why do you want to use the module

You develop code that makes use of the AWS SDK for JavaScript v3. You are already writing tests for it through the great aws-sdk-client-mock package. You also want to ensure that your actual code performs certain calls against your AWS Client Mocks. While there is aws-sdk-client-mock-jest you prefer vitest.

You can use this module to use expect extensions for vitest to ensure certain commands have been called on your AWS clients.

Install

npm install --save-dev aws-sdk-client-mock-vitest

You must register the new matchers explicity (think about putting this to a setup file). Feel free to only extend the matchers you are intending to use

/*
  you may want to put the following into a file tests/setup.ts
  and then specify your vite.config.ts as such

      import { defineConfig } from "vitest/config";

      export default defineConfig({
        test: {
          setupFiles: ["tests/setup.ts"],
        },
      });

  to add the custom mat chers before each test run
*/
import { expect } from "vitest";
import {
  toReceiveCommandTimes,
  toHaveReceivedCommandTimes,
  toReceiveCommandOnce,
  toHaveReceivedCommandOnce,
  toReceiveCommand,
  toHaveReceivedCommand,
  toReceiveCommandWith,
  toHaveReceivedCommandWith,
  toReceiveNthCommandWith,
  toHaveReceivedNthCommandWith,
  toReceiveLastCommandWith,
  toHaveReceivedLastCommandWith,
} from "aws-sdk-client-mock-vitest";

expect.extend({
  toReceiveCommandTimes,
  toHaveReceivedCommandTimes,
  toReceiveCommandOnce,
  toHaveReceivedCommandOnce,
  toReceiveCommand,
  toHaveReceivedCommand,
  toReceiveCommandWith,
  toHaveReceivedCommandWith,
  toReceiveNthCommandWith,
  toHaveReceivedNthCommandWith,
  toReceiveLastCommandWith,
  toHaveReceivedLastCommandWith,
});

In case you are using typescript, create a vitest.d.ts file with the following content

// tests/vitest.d.ts
import "vitest";
import { CustomMatcher } from "aws-sdk-client-mock-vitest";

declare module "vitest" {
  interface Assertion<T = any> extends CustomMatcher<T> {}
  interface AsymmetricMatchersContaining extends CustomMatcher {}
}

If you get the following error in your tests

Error: Invalid Chai property: toHaveReceivedCommandWith

Then your probably forgot to run expect.extend with the matcher you are using in your test (see above)

Sample usage

Lets assume you have code that retrieves a secret from the AWS Secrets Manager

// src/main.ts
import {
  SecretsManagerClient,
  GetSecretValueCommand,
} from "@aws-sdk/client-secrets-manager";

export async function readSecret(secretId: string): Promise<string> {
  const client = new SecretsManagerClient({});
  const command = new GetSecretValueCommand({ SecretId: secretId });
  const response = await client.send(command);
  if (response.SecretString) {
    return response.SecretString;
  }
  throw new Error("Unable to read the secret");
}

You can test this with vite without doing any network requests thanks to aws-sdk-client-mock

// tests/main.test.ts
import { describe, it, expect } from "vitest";
import { mockClient } from "aws-sdk-client-mock";
import {
  GetSecretValueCommand,
  SecretsManagerClient,
} from "@aws-sdk/client-secrets-manager";

import { readSecret } from "../src/main";

const smMock = mockClient(SecretsManagerClient);

describe("readSecret", () => {
  it("should return the secret value", async () => {
    /* Setup our mock. In this test the secret will always be secr3t */
    smMock.on(GetSecretValueCommand).resolves({ SecretString: "secr3t" });

    const result = await readSecret("foo");
    expect(result).toBe("secr3t");

    // We have not verified that we actually interacted with our
    // Secret Manager correcty
  });
});

But we may want to actually inspect our mock client to verify that we actually have sent a specific command. We can do this by changing our testfile and registering custom matchers.

// tests/main.test.ts
import { describe, it, expect } from "vitest";
import { mockClient } from "aws-sdk-client-mock";
import {
  GetSecretValueCommand,
  SecretsManagerClient,
} from "@aws-sdk/client-secrets-manager";

import {
  CustomMatcher,
  toHaveReceivedCommandWith,
} from "aws-sdk-client-mock-vitest";

/* you can also run this in setupTests, see above */
expect.extend({ toHaveReceivedCommandWith });

/* You may want to put this in some vitest.d.ts, see above */
declare module "vitest" {
  interface Assertion<T = any> extends CustomMatcher<T> {}
  interface AsymmetricMatchersContaining extends CustomMatcher {}
}

import { readSecret } from "../src/main";

const smMock = mockClient(SecretsManagerClient);

describe("readSecret", () => {
  it("should read it", async () => {
    smMock.on(GetSecretValueCommand).resolves({ SecretString: "secr3t" });

    const result = await readSecret("foo");
    expect(result).toBe("secr3t");

    /* Ensure we use the inut of the function to fetch the correct secret */
    expect(smMock).toHaveReceivedCommandWith(GetSecretValueCommand, {
      SecretId: "foo",
    });
  });
});

Running test

In order to run tests locally, execute the following

npm ci
npm run test:coverage

If you get an ERR_INSPECTOR_NOT_AVAILABLE error, make sure your nodejs is compiled with inspector support. Otherwise run npm run test to skip code coverage

Thank you

I would like to thank Maciej Radzikowski for the awesome aws-sdk-client-mock and aws-sdk-client-mock-jest packages. These helped a lot testing AWS code and also helped building this library

aws-sdk-client-mock-vitest's People

Contributors

stschulte avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.