Skip to main content

Unit Testing Custom Components

Unit testing is an incredibly important part of software development. You want to catch errors and breaking changes before they wreak havoc on your customers' integrations.

By creating a series of unit tests for your custom components, your development team can feel comfortable updating custom component code without the risk of introducing regressions. Plus, when you write unit tests you're creating sample use cases for your component, which yields documentation-as-code for your custom component.

Today let's work through adding unit tests to a sample custom component.

Unit testing with Jest

There are numerous JavaScript testing frameworks available, but we'll use Jest for this tutorial.

Add tests to the Hello Prismatic component

In the Hello Prismatic tutorial, you build a custom component that takes a first name and last name as inputs, and returns a message that greets the user. Let's verify that the component works as expected by adding unit tests.

  1. First, create a test file by adding an index.test.ts file to the src/ directory.

  2. Next, import the testing harness from the Primsatic custom component SDK, create a test harness, and write a few test cases for the myAction action.

    index.test.ts
    // Import the Prismatic custom component SDK testing harness
    import { createHarness } from "@prismatic-io/spectral/dist/testing";

    // Import your component from index.ts
    import myComponent from ".";

    // Create a new test harness
    const harness = createHarness(myComponent);

    // Test your component
    describe("Test the myAction action", () => {
    test("Test what happens if both first and last name are provided", async () => {
    // Invoke the action by name
    const result = await harness.action("myAction", {
    firstName: "John", // These keys should match the action's input keys
    lastName: "Doe",
    });
    // Declare your expectations - a unit test will fail if this expectation is not met
    expect(result?.data).toBe("Hello John Doe!");
    });

    test("Test what happens if first name is an empty string", async () => {
    const result = await harness.action("myAction", {
    firstName: "",
    lastName: "Doe",
    });

    expect(result?.data).toBe("Hello Doe!");
    });
    });
    1. Finally, run your tests with npm run test and verify that your unit tests pass.

If your tests pass, you will see a set of green checkmarks in your terminal.

If someone from your team adjusts the myAction action to return a different message, your unit tests will fail and you'll know that you need to update your code, or update your integration.

Test actions that require a connection

In the Wrap an API in a Component tutorial, you build a custom component that wraps a mock API. That component included a connection with an API key.

Let's look at two different ways to supply that connection to a unit test:

Option 1 - Source the connection information from environment variables.

You can use the process.env object to access environment variables in your unit tests. This is a great option if you want to run your unit tests in a CI/CD pipeline.

index.test.ts
import {
createConnection,
createHarness,
} from "@prismatic-io/spectral/dist/testing";
import myComponent from ".";
import { acmeErpConnection } from "./connections";

const harness = createHarness(myComponent);

// Create a connection to be used by the action test
const myConnection = createConnection(acmeErpConnection, {
baseUrl: "https://my-json-server.typicode.com/prismatic-io/placeholder-data",
apiKey: process.env.ACME_API_KEY, // Source the API key from an environment variable
});

describe("Test the get item by ID action", () => {
test("Ensure the get item by ID action returns an item", async () => {
const result = await harness.action("getItemById", {
connection: myConnection,
itemId: "1",
});
expect(result?.data).toEqual({
id: 1,
name: "Widgets",
quantity: 20,
});
});
});

When running your test, you can supply an ACME_API_KEY environment variable by setting it in an .env file, by passing it in as a command line argument, or by exporting it in your terminal.

Option 2 - Pull the connection information from an existing connection in Prismatic

Assuming you already have a valid connection in an existing Prismatic integration, you can instruct prism to fetch the connection's information from Prismatic and use it in your unit tests. The connection that you fetch will be accesible from an environment variable named PRISMATIC_CONNECTION_VALUE.

Look at your browser's address bar when viewing your integration in Prismatic, and copy the SW5.... portion of the URL. That is your integration's ID.

You can then print your connection's value to the console by running the following command:

prism components:dev:run \
--integrationId SW50ZWdyYXRpb246YmU1N2NlYTgtYjQ4Ny00YWEzLTk0ZTktZDA4NmJiNmM2Yzdi \
--connectionKey "Acme ERP Connection" -- printenv PRISMATIC_CONNECTION_VALUE | jq

You should see a JSON object that contains your connection's information.

That JSON string can be parsed and referenced in your unit test. Or, the harness.connectionValue method will take care of parsing the JSON and returning a connection object that can be used in your unit test for you.

index.test.ts with connection from Prismatic
import { createHarness } from "@prismatic-io/spectral/dist/testing";
import myComponent from ".";
import { acmeErpConnection } from "./connections";

const harness = createHarness(myComponent);
const myConnection = harness.connectionValue(acmeErpConnection);

describe("Test the get item by ID action", () => {
test("Ensure the get item by ID action returns an item", async () => {
const result = await harness.action("getItemById", {
connection: myConnection,
itemId: "1",
});
expect(result?.data).toEqual({
id: 1,
name: "Widgets",
quantity: 20,
});
});
});

To invoke the unit test with the connection from Prismatic, run prism components:dev:run along with npm run test:

prism components:dev:run \
--integrationId SW50ZWdyYXRpb246YmU1N2NlYTgtYjQ4Ny00YWEzLTk0ZTktZDA4NmJiNmM2Yzdi \
--connectionKey "Acme ERP Connection" -- npm run test