最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Merge hooks in QUnit - Stack Overflow

programmeradmin4浏览0评论

I need to reuse sets of setup and cleanup logic in multiple QUnit modules without code duplication. These pieces of logic are already encoded as "module hook" objects as per the QUnit API. Some of the hooks might be async. Here is an example - The content of these hooks doesn't really mean anything, it's just for demonstration.

const fruitHook = {
  async before () {
    this.banana = { ripeness: await generateRandomInitialRipeness() };
    this.apple = { ripeness: await generateRandomInitialRipeness() };
  },

  beforeEach () {
    this.banana.ripeness += 1;
    this.apple.ripeness += 1;
  }
};

const nutHook = {
  before () {
    this.walnut = { cracked: false };
    this.peanut = { cracked: false };
  }
};

I would like to combine these hooks in different ways as needed by my QUnit modules.

// This module needs the fruitHook
QUnit.module('TestFruits', fruitHook);

// This module needs the nutHook
QUnit.module('TestNuts', nutHook);

// This module needs both
QUnit.module('TestFruitsAndNuts', /* ??? */);

In a real use case, I would have a larger set of hooks that need to be combined into various different subsets. Does QUnit offer a way to combine these hooks?

I can write my own "hooks concatenator" utility:

function concatenateHooks (hooks) {
  const resultingHook = {
    async before () {
      for (const hook of hooks) {
        if (typeof hook.before === 'function') {
          await hook.before.call(this);
        }
      }
    },

    async beforeEach () { /* ... */ }

    async afterEach () { /* ... */ }

    async after () { /* ... */ }
  }
}

And use it like so:

QUnit.module('TestFruitsAndNuts', concatenateHooks([fruitHook, nutHook]);

In my implementation I'm forcing all hooks to become async, though I suspect I could make it a bit more elaborate to avoid awaiting if all passed hooks are synchronous.

Is there a feature in QUnit that does this and that I've missed?

I need to reuse sets of setup and cleanup logic in multiple QUnit modules without code duplication. These pieces of logic are already encoded as "module hook" objects as per the QUnit API. Some of the hooks might be async. Here is an example - The content of these hooks doesn't really mean anything, it's just for demonstration.

const fruitHook = {
  async before () {
    this.banana = { ripeness: await generateRandomInitialRipeness() };
    this.apple = { ripeness: await generateRandomInitialRipeness() };
  },

  beforeEach () {
    this.banana.ripeness += 1;
    this.apple.ripeness += 1;
  }
};

const nutHook = {
  before () {
    this.walnut = { cracked: false };
    this.peanut = { cracked: false };
  }
};

I would like to combine these hooks in different ways as needed by my QUnit modules.

// This module needs the fruitHook
QUnit.module('TestFruits', fruitHook);

// This module needs the nutHook
QUnit.module('TestNuts', nutHook);

// This module needs both
QUnit.module('TestFruitsAndNuts', /* ??? */);

In a real use case, I would have a larger set of hooks that need to be combined into various different subsets. Does QUnit offer a way to combine these hooks?

I can write my own "hooks concatenator" utility:

function concatenateHooks (hooks) {
  const resultingHook = {
    async before () {
      for (const hook of hooks) {
        if (typeof hook.before === 'function') {
          await hook.before.call(this);
        }
      }
    },

    async beforeEach () { /* ... */ }

    async afterEach () { /* ... */ }

    async after () { /* ... */ }
  }
}

And use it like so:

QUnit.module('TestFruitsAndNuts', concatenateHooks([fruitHook, nutHook]);

In my implementation I'm forcing all hooks to become async, though I suspect I could make it a bit more elaborate to avoid awaiting if all passed hooks are synchronous.

Is there a feature in QUnit that does this and that I've missed?

Share Improve this question edited Mar 9 at 16:24 antonio asked Mar 9 at 14:09 antonioantonio 4391 gold badge3 silver badges13 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

You can use QUnit's module scope to add as many hooks as you need.

QUnit.module('Foo', function (hooks) {
  hooks.beforeEach(function () {
    this.a = 'Hello';
  });

  hooks.beforeEach(function () {
    this.b = ' world';
  });

  QUnit.test('example', function (assert) {
    assert.equal(this.a + this.b, 'Hello world');
  });
});

To provide shared helper function that install shooks, I recommend passing the hooks object, like so:

function setupFruit(hooks) {
  hooks.beforeEach(function () {
    this.a = 'Hello';
  });
}

function setupVeg(hooks) {
  hooks.beforeEach(function () {
    this.b = ' world';
  });
}

QUnit.module('Foo', function (hooks) {
  setupFruit(hooks);
  setupVeg(hooks);

  QUnit.test('example', function (assert) {
    assert.equal(this.a + this.b, 'Hello world');
  });
});

Alternatively, if something is needed across all your modules, you can also use a global hook via QUnit.hooks since QUnit 2.18, so that it can be part of all modules without needing to call the shared helper from each module.

Docs:

  • https://qunitjs/api/QUnit/module/#hooks
  • https://qunitjs/lifecycle/#module-hooks
发布评论

评论列表(0)

  1. 暂无评论