【问题标题】:Best Way to Test Promises in Jest在 Jest 中测试 Promise 的最佳方法
【发布时间】:2017-08-19 15:19:54
【问题描述】:

除非我有什么误解,否则解析和拒绝 (https://facebook.github.io/jest/docs/expect.html#resolves) 将在 vNext 之前可用。现在/同时使用 Jest 测试 Promise 的推荐方法是什么?是否只是将期望放在 thens 和 catchs 中?

例如:

describe('Fetching', () => {
    const filters = {
        startDate: '2015-09-01'
    };
    const api = new TestApiTransport();

    it('should reject if no startdate is given', () => {
        MyService.fetch().catch(e => expect(e).toBeTruthy()); // see rejects/resolves in v20+
    });            

    it('should return expected data', () => {
        MyService.fetch(filters, null, api).then(serviceObjects => {
            expect(serviceObjects).toHaveLength(2);
        }).catch(e => console.log(e));
    });            
});

2019 年 6 月 15 日更新:在我发布这个问题后不久,Jest 就开始支持这个问题。我更改了下面接受的答案,以反映当前执行此操作的最佳方法。

2021 年 12 月 8 日更新:在某个时候,Jest 开始支持 async/await。因此,虽然其他方法注意到工作,我已经采取简单(在大多数情况下)使用类似的东西:

it('should do something', async () => {
    const expected = true; 
    expect(await funcToTest()).toEqual(expected);
});

与大多数情况一样,async/await 比替代方案更具可读性。我现在使用resolvesrejects 的唯一情况是针对以下简单情况:

it('should not throw when doing something', async () => {
    await expect(funcToTest()).resolves.not.toThrow();
});

it('should throw when something is wrong', async () => {
    await expect(funcToTest()).rejects.toThrow();
});

【问题讨论】:

    标签: javascript promise jestjs


    【解决方案1】:

    现在你也可以这样写:docs

    describe('Fetching', () => {
        const filters = {
            startDate: '2015-09-01'
        };
        const api = new TestApiTransport(); 
    
     it('should reject if no startdate is given', () => {
       expect.assertions(1);
       return expect(MyService.fetch()).rejects.toEqual({
         error: 'Your code message',
       });
     });          
    
    
     it('should return expected data', () => {
       expect.assertions(1);
       return expect(MyService.fetch(filters, null, api)).resolves.toEqual(extectedObjectFromApi);
     });            
    });
    

    更新 (06.01.2019)

    同意接受的答案不能正常工作 expect.assertions(1); 做了所有的魔法。 Link to docs

    expect.assertions(number) 验证一定数量的断言 在测试期间被调用。这在测试时通常很有用 异步代码,以确保回调中的断言 实际上被调用了。

    因此,将此行放在顶部将控制在运行测试时生成的特定 数量 个断言。

    【讨论】:

    • 感谢您提供实际有效的答案,这与大多数 SO 答案或异步测试的 Jest 文档不同。
    【解决方案2】:

    resolvecatch 中返回一个promise 和expect

    describe('Fetching', () = > {
      const filters = {
        startDate: '2015-09-01'
      };
      const api = new TestApiTransport();
      it('should reject if no startdate is given', () = > {
        return MyService.fetch()
          .catch (e => expect(e).toBeTruthy()); // see rejects/resolves in v20+
      });
      it('should return expected data', () = > {
        return MyService.fetch(filters, null, api)
          .then(serviceObjects => {
            expect(serviceObjects).toHaveLength(2);
          })
      });
    });
    

    或使用async/await

    describe('Fetching', () = > {
      const filters = {
        startDate: '2015-09-01'
      };
      const api = new TestApiTransport();
      it('should reject if no startdate is given', async() = > {
        try {
          const r = await MyService.fetch()
        } catch (e) {
          expect(e).toBeTruthy()
        }
      });
      it('should return expected data', async() = > {
        const serviceObjects = await MyService.fetch(filters, null, api)
        expect(serviceObjects).toHaveLength(2);
      });
    });
    

    【讨论】:

    • 你必须回报承诺。用你的例子更新了我的答案
    • 谢谢。我现在添加了回报。我没有看到不同的结果,但我假设让框架知道等待解决或其他什么?
    • 为什么我的测试仍然通过但我收到一条红色消息说期望没有工作?我通过了所有测试,但结果与我当时的预期不符。
    • 对于使用async 我很确定你需要使用done() 函数并手动调用它。
    • 您应该在拒绝测试的开头添加expect.assertions(1)。因为无论fetch是否失败,测试都会通过。
    【解决方案3】:

    我能够使用 AXIOS 测试 JEST 以进行这样的 HTTP REST 调用。

    it('has an API worth testing', async () => {
      let httpResult = null;
      await callThefunctionThatReturnsPromiseToMakeTheAxiosApiCall()
        .then(function(result) {httpResult=result;})
        .catch(function(err) {httpResult=err;});
      expect(httpResult.data.myData).toBe("myExpectedValue");
    });
    

    it('has an API worth testing', async () => {
      let httpResult = await callThefunctionThatReturnsPromiseToMakeTheAxiosApiCall();
      expect(httpResult.data.myData).toBe("myExpectedValue");
    });
    

    【讨论】:

      猜你喜欢
      • 2020-04-21
      • 2018-10-06
      • 2018-07-06
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 2015-10-01
      • 1970-01-01
      • 2015-09-21
      相关资源
      最近更新 更多