【问题标题】:Async Jasmine unit test wrong order异步 Jasmine 单元测试错误的顺序
【发布时间】:2022-01-14 08:06:36
【问题描述】:

我有一个onBlur 函数,该函数在激活输入模糊时执行。在这个异步 onBlur 函数中,我 await 来自另一个函数的响应。当我尝试对此进行测试时,执行顺序似乎是错误的。我已经放入了三个 console.logs() 来检查似乎不正确的执行顺序。

是什么导致这个订单出错? nextTick()不会保证async函数需要在测试结束之前完成吗?

it('executes startDate when blur is triggered on search', async function(done) {
      // GIVEN an instantiated SearchDate
      // WHEN validateStartDate is spied upon and blur is triggered
      const spyValidateStartDate = spyOn(SearchDate.methods, 'validateStartDate').and.callThrough();

      wrapper = shallowMount(
        Search,
        {
          localVue: this.localVue,
          propsData: props,
        },
      );

      const searchStartDateElement = wrapper.find('#searchStartDate');
      searchStartDateElement.element.value = '01-01-2018';
      await searchStartDateElement.trigger('blur');

      // THEN expect datepickerStartDate to have the correct date
      wrapper.vm.$nextTick(() => {
        expect(spyValidateStartDate).toHaveBeenCalled();
        console.log('3');
        expect(wrapper.vm._data.datepickerStartDate).toEqual(new Date('2018-01-01'));
        done();
      });
    });

以及Vue中的模糊功能

async onBlur(event) {
      console.log('1');
      this.datepickerStartDate = await this.validateDateField(event.target.getAttribute('name'), event.target.value);
      console.log('2');
    },

console.log()的当前顺序是1, 3, 2

validateDateField 函数

    async validateDateField(name, value) {
      const valid = await this.$validator.validate(name);
      if (!valid || !value) {
        return null;
      }

      const splittedInput = value.split('-');
      return new Date(`${ splittedInput[2] }-${ splittedInput[1] }-${ splittedInput[0] }`);
    },

【问题讨论】:

  • “nextTick() 不会确保异步函数需要在测试结束之前完成吗?” - 当然没有。你不能指望这一点,除非你确定你使用的 api 处理承诺。在事件监听器和许多其他地方,Promise 被忽略了。测试的方式取决于 validateDateField。为什么是异步的?
  • validateDateField 需要来自 $.validator 的异步值。我已将 validateDateField 函数添加到原始问题中。

标签: vue.js unit-testing async-await jasmine


【解决方案1】:

nextTick 可用于承诺控制流,但它无法感知用户代码中发生的任何异步操作。问题是 validateDateField 是异步的,但在测试中没有等待,这会导致竞争条件。它返回的 Promise 应该链接在测试中以保持正确的执行顺序。

现代测试框架支持 Promise,同时使用 asyncdone 是一种反模式。这使得测试更加复杂和容易出错。这可能会妨碍正确处理错误。万一done由于某种情况没有被调用,这会导致测试超时。

可以是:

async function() {
  const spyValidateStartDate = spyOn(SearchDate.methods, 'validateStartDate').and.callThrough();
  ...

  searchStartDateElement.trigger('blur');
  await wrapper.vm.$nextTick();
  expect(spyValidateStartDate).toHaveBeenCalled();
  const dataResult = await spyValidateStartDate.calls.first().returnValue;
  // Can also assert the result for more rigid test
  expect(wrapper.vm._data.datepickerStartDate).toEqual(new Date('2018-01-01'));
}

【讨论】:

    猜你喜欢
    • 2017-06-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    相关资源
    最近更新 更多