Skip to main content

Import

import { invoke } from "@prismatic-io/spectral/dist/testing";

Signature

export const invoke = async <
  TInputs extends Inputs,
  TConfigVars extends ConfigVarResultCollection,
  TAllowsBranching extends boolean,
  TReturn extends ActionPerformReturn<TAllowsBranching, unknown>,
>(
  { perform }: ActionDefinition<TInputs, TConfigVars, TAllowsBranching, TReturn>,
  params: ActionInputParameters<TInputs>,
  context?: Partial<ActionContext<TConfigVars>>,
): Promise<InvokeReturn<TReturn>>
invoke calls the perform function of an ActionDefinition with mock context and the params you provide. It returns both the action result and a mock logger you can assert against.

Parameters

action
ActionDefinition
required
The action definition object to invoke. Only the perform function is used.
params
ActionInputParameters<TInputs>
required
An object containing the input parameter values for the action. Keys must match the input keys defined on the action.
context
Partial<ActionContext<TConfigVars>>
Optional partial action context. Overrides the default mock context that invoke constructs automatically. Use this to supply custom configVars, instanceState, or other context fields.

Return value

interface InvokeReturn<ReturnData> {
  result: ReturnData;
  loggerMock: ActionLogger;
}
result
TReturn
required
The value returned by the action’s perform function.
loggerMock
ActionLogger
required
A mock logger with jest/vitest spy functions for each log level. Use this to assert that your action logged expected messages.

Examples

import { action, input } from "@prismatic-io/spectral";
import { invoke } from "@prismatic-io/spectral/dist/testing";
import { describe, expect, it } from "vitest";

const greetAction = action({
  display: { label: "Greet", description: "Returns a greeting" },
  inputs: {
    name: input({ label: "Name", type: "string" }),
  },
  perform: async (context, { name }) => {
    context.logger.info(`Greeting ${name}`);
    return { data: `Hello, ${name}!` };
  },
});

describe("greetAction", () => {
  it("returns a greeting", async () => {
    const { result } = await invoke(greetAction, { name: "Alice" });
    expect(result.data).toBe("Hello, Alice!");
  });

  it("logs the greeting", async () => {
    const { loggerMock } = await invoke(greetAction, { name: "Alice" });
    expect(loggerMock.info).toHaveBeenCalledWith("Greeting Alice");
  });
});
Destructure result and loggerMock in a single line:
const { result, loggerMock } = await invoke(myAction, params);

Build docs developers (and LLMs) love