How to unit test azure durable function in javascript for v4?

76 Views Asked by At

how to write unit test case of this durable function. it is calling through app and df, so it does not have any function. how can i call the trigger and orchestrator? Here is my code

const { app } = require('@azure/functions');
const df = require('durable-functions');

const { autoDeleteBackUpActivity, autoDeleteBackUpDeterminer } = require('../activity/autoDeleteBackUpActivity');

df.app.orchestration('AutoDeleteBackupOrchestrator', function* (context) {
  const backupDatabasesToBeRemoved = yield context.df.callActivity('AutoDeleteBackUpDeterminer');

  const parallelTasks = [];
  for (const backupDatabase of backupDatabasesToBeRemoved) {
    parallelTasks.push(
      context.df.callActivity(
        'AutoDeleteBackUpActivity',
        backupDatabase
      )
    );
  }
  if (parallelTasks.length > 0) {
    yield context.df.Task.all(parallelTasks);
  }
});

df.app.activity('AutoDeleteBackUpDeterminer', {
  handler: autoDeleteBackUpDeterminer
});

df.app.activity('AutoDeleteBackUpActivity', {
  handler: autoDeleteBackUpActivity
});

app.timer('AutoDeleteBackupTimerTrigger', {
  schedule: '0 0 2 * * *',
  extraInputs: [df.input.durableClient()],
  handler: async (myTimer, context) => {
    const client = df.getClient(context);
    const instanceId = await client.startNew('AutoDeleteBackupOrchestrator');
    context.log('[Auto-Delete-Backup]: Started orchestration with ID: ', instanceId);
  }
});

is there any testing util is available for v4 javascript durable function? how we can write unit test case of these code.

1

There are 1 best solutions below

0
SiddheshDesai On

You can make use of Jest library to Create Unit Test for Azure Function, Just install the jest package from npm. Create one Tests folder and a test file with js extension inside it, Then run the npx jest command to run the test:-

Install jest package:-

npm i jest
npx jest

In your Function project create one folder and add js file:- __tests__/autoDeleteBackup.test.js file:-

autoDeleteBackup.test.js:-

// __tests__/autoDeleteBackup.test.js

const { AutoDeleteBackupOrchestrator } = require('../src/functions/autoDeleteBackup');
const { autoDeleteBackUpActivity, autoDeleteBackUpDeterminer } = require('../activity/autoDeleteBackUpActivity');

// Mocking the durable-functions module
jest.mock('durable-functions', () => {
    const mDurableFunctions = {
        df: {
            callActivity: jest.fn(),
            Task: {
                all: jest.fn((tasks) => Promise.all(tasks)),
            },
        },
        app: {
            orchestration: jest.fn(),
            activity: jest.fn(),
            timer: jest.fn(),
        },
        input: {
            durableClient: jest.fn(),
        },
        getClient: jest.fn(),
    };
    return mDurableFunctions;
});

describe('AutoDeleteBackupOrchestrator', () => {
    test('should call AutoDeleteBackUpDeterminer and AutoDeleteBackUpActivity for each backup database', async () => {
        const context = {}; // Mock context object
        const backupDatabasesToBeRemoved = ['database1', 'database2', 'database3'];
        const mockCallActivity = jest.fn();

        // Mocking callActivity functions
        const df = require('durable-functions');
        df.df.callActivity.mockImplementation((activityName, backupDatabase) => {
            mockCallActivity(activityName, backupDatabase);
            return Promise.resolve();
        });

        // Call the orchestrator function
        await AutoDeleteBackupOrchestrator(context);

        // Expect AutoDeleteBackUpDeterminer to be called once
        expect(df.df.callActivity).toHaveBeenCalledWith('AutoDeleteBackUpDeterminer');

        // Expect AutoDeleteBackUpActivity to be called for each backup database
        expect(mockCallActivity.mock.calls.length).toBe(backupDatabasesToBeRemoved.length);
        backupDatabasesToBeRemoved.forEach((backupDatabase, index) => {
            expect(mockCallActivity.mock.calls[index][0]).toBe('AutoDeleteBackUpActivity');
            expect(mockCallActivity.mock.calls[index][1]).toBe(backupDatabase);
        });

        // Expect df.Task.all to be called once with parallelTasks array
        expect(df.df.Task.all).toHaveBeenCalledWith(expect.any(Array));
    });
});

Now, Run the command below:-

npx jest

Output:-

enter image description here

Azure Durable Function Javascript v4 Durable Orchestrator Default Function code Test:-

// __tests__/durableHello1.test.js

const { durableHello1Orchestrator } = require('../src/functions/durableHello1');

// Mocking the durable-functions module
jest.mock('durable-functions', () => {
    const mDurableFunctions = {
        df: {
            callActivity: jest.fn(),
        },
        app: {
            orchestration: jest.fn(),
            activity: jest.fn(),
            http: jest.fn(),
        },
        input: {
            durableClient: jest.fn(),
        },
        getClient: jest.fn(),
    };
    return mDurableFunctions;
});

describe('durableHello1Orchestrator', () => {
    test('should return outputs containing greetings for given cities', async () => {
        const context = {}; // Mock context object
        const expectedOutputs = ['Hello, Tokyo', 'Hello, Seattle', 'Hello, Cairo'];
        
        // Mocking callActivity function
        const df = require('durable-functions');
        df.df.callActivity.mockResolvedValueOnce('Hello, Tokyo');
        df.df.callActivity.mockResolvedValueOnce('Hello, Seattle');
        df.df.callActivity.mockResolvedValueOnce('Hello, Cairo');
        
        const result = await durableHello1Orchestrator(context);
        
        expect(result).toEqual(expectedOutputs);
    });
});

Output:-

enter image description here

Reference:-

Azure function nodejs v4 test mode - Stack Overflow My answer