temporalio / temporalio/sdk-typescript

[Feature Request] Allow for easy mocking

Open
#665 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
TypeScript
Stars
917
Forks
224
Avg merge
3d 16h
Merged PRs (30d)
43

Description

Is your feature request related to a problem? Please describe.

Mocking an SDK function is difficult. If you use a system like Sinon that depends on default exports, it doesn't work, since we don't do default exports. Even if you use a system like Jest that allows you to mock the whole package, there are two issues:

  • Unless your code only uses a single function, you have to mock or add back in the other functions. This, for instance, creates a package that only exports proxyActivities:
const mockRequest = jest.fn<Promise<string>, []>();
mockRequest.mockResolvedValue('3');

test('httpWorkflow with mocked proxyActivities', async () => {
  jest.mock('@temporalio/workflow', () => ({
    proxyActivities: mockRequest,
  }));

  expect(await httpWorkflow()).toBe('The answer is 3');
});
  • When you mock, you have to recreate the environment. For instance, if you run the above, you get:
 FAIL  src/workflows.test.ts (9.489 s)
  ● httpWorkflow with mocked proxyActivities

    TypeError: exports.storage.getStore is not a function

      14 |
      15 | export async function httpWorkflow(): Promise<string> {
    > 16 |   const answer = await makeHTTPRequest();
         |                        ^
      17 |   return `The answer is ${answer}`;
      18 | }
      19 |

      at Function.current (node_modules/@temporalio/workflow/src/cancellation-scope.ts:156:20)
      at node_modules/@temporalio/workflow/src/workflow.ts:151:37
      at scheduleActivityNextHandler (node_modules/@temporalio/workflow/src/workflow.ts:150:10)
      at scheduleActivity (node_modules/@temporalio/workflow/src/workflow.ts:259:10)
      at node_modules/@temporalio/workflow/src/workflow.ts:493:18
      at httpWorkflow (src/workflows.ts:16:24)
      at Object.<anonymous> (src/workflows.test.ts:67:28)
Solution

The current solution in the case of proxyActivities is to run a Worker with a test connection and mock activities (like this), and to start a workflow using the test client. If you want to test a helper function used by workflows, then tell the Worker the helper is a workflow and start it, like this:

// workflow-helpers.ts
export function myHelper() { ... }
// workflow-helpers.test.ts
  const worker = await Worker.create({
    workflowsPath: require.resolve('./workflow-helpers'),
    ...
  });
  await withWorker(worker, async () => {
    const result = await workflowClient.execute(myHelper, {
      workflowId: uuid4(),
      taskQueue: 'test',
    });
    expect(result).toEqual('The answer is 99');
  });  
Feedback

If the current solution described above doesn't work for your case, or isn't ideal for you, let us know in this thread! ☺️

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the mocked workflow example in src/workflows.test.ts and compare it with the Worker-based testing approach described in the issue. Define the desired mocking behavior and identify tests that demonstrate it without requiring callers to recreate the workflow environment; the issue does not name an implementation entry point or specific completion criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.