javascript - 如何在 javascript 中为 azure 持久函数编排实现基本单元测试

标签 javascript unit-testing azure-durable-functions

什么是单元测试,它会在下面的协调器中伪造对 callActivity 的调用,以返回已知值并期望协调器返回该值。

用于单元测试的 azure 持久函数文档中的示例 [1] 都是用 C# 编写的,我无法复制 尽管进行了多次尝试,但还是用 javascript 实现了它们。这是因为我不知道如何使用虚假上下文构建编排器。

  const df = require('durable-functions');

  module.exports = df.orchestrator(function* orchestratorFunctionGenerator(context) {
    const input = context.df.getInput();
    const apimApiName = input.apimApiName;
    const indexNames = yield context.df.callActivity('GetIndexNames', apimApiName);
    const indexerName = indexNames.idle;
    const indexerStatus = yield context.df.callActivity('GetIndexerStatus', indexerName);
    return indexerStatus;
  });

[1] https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-unit-testing

最佳答案

我们采用的方法是将生成器方法提取到它自己的模块中。

module.exports = function* orchestratorFunctionGenerator(context) {
  const input = context.df.getInput();
  const apimApiName = input.apimApiName;
  const indexNames = yield context.df.callActivity('GetIndexNames', apimApiName);
  const indexerName = indexNames.idle;
  const indexerStatus = yield context.df.callActivity('GetIndexerStatus', indexerName);
  return indexerStatus;
};

然后需要它

const df = require('durable-functions');
const generatorFunction = require('./generator-function');

module.exports = df.orchestrator(generatorFunction);

然后单独测试该功能

const chai = require('chai');
const sinon = require('sinon');
const getIndexerStatusOrchestratorGenerator = require('../../GetIndexerStatusOrchestrator/generator-function');

const expect = chai.expect;

function iterateGenerator(generator) {
  let result = generator.next();
  while (!result.done) {
    result = generator.next(result.value);
  }
  return result;
}

describe('getIndexerStatusOrchestrator', () => {
  it('happy path should return \'inProgress\'', () => {
    const indexNames = { active: 'index-1', idle: 'index-2' };
    const apimApiName = 'api';
    const input = { apimApiName };
    const stubCallActivity = sinon.stub();
    stubCallActivity.withArgs('GetIndexNames', apimApiName).returns(indexNames);
    stubCallActivity.withArgs('GetIndexerStatus', indexNames.idle).returns('inProgress');

    const context = {
      df: {
        callActivity: stubCallActivity,
        getInput: sinon.fake.returns(input),
      },
    };

    const generator = getIndexerStatusOrchestratorGenerator(context);

    const result = iterateGenerator(generator);
    expect(result.value).to.equal('inProgress');
  });
  it('indexer status should be for the idle index', () => {
    const indexNames = { active: 'index-1', idle: 'index-2' };
    const apimIndexName = 'api';
    const input = { apimApiName: apimIndexName };
    const stubCallActivity = sinon.stub();
    stubCallActivity.withArgs('GetIndexNames', apimIndexName).returns(indexNames);
    stubCallActivity.withArgs('GetIndexerStatus', indexNames.idle);
    // use stub as a mock since we need both stub and mock behaviour
    // for 'callActivity' and this was the easier option
    stubCallActivity.withArgs('GetIndexerStatus').callsFake((method, indexerName) => {
      expect.fail(`Unexpected indexer name ${indexerName}`);
    });

    const context = {
      df: {
        callActivity: stubCallActivity,
        getInput: sinon.fake.returns(input),
      },
    };

    const generator = getIndexerStatusOrchestratorGenerator(context);

    iterateGenerator(generator);

    // expectations set above
  });
});

正如预期的那样,这是一个简单的协调器示例。我们的协调器具有更多的逻辑,并且测试将具有更多值(value)。

此外,我个人不会在第二次测试中使用模拟方法,而只会依靠使用 stub 来测试输出来伪造依赖项交互。

关于javascript - 如何在 javascript 中为 azure 持久函数编排实现基本单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54863516/

相关文章:

c# - 如何在本地管理 Azure Durable 功能任务中心?

c# - Azure Functions 和 Azure Durable Function 之间有什么区别

javascript - 从 Cordova 应用程序打开 native 谷歌地图

javascript - React hooks 状态不使用最新版本

c# - 如何在 .net 中使用 C# 对默认构造函数类进行单元测试?

C# 如何测试对接口(interface)的引用

javascript - 返回模板表中行和列的索引

javascript - Ember-CLI 应用程序中的常规站点相关设置?

java - 对 Hibernate 驱动的应用程序进行单元测试?

azure - 尝试了解 Azure Durable Function 上下文