【问题标题】:In Jest, how can I make a test fail?在 Jest 中,我怎样才能使测试失败?
【发布时间】:2017-06-29 19:41:22
【问题描述】:

我知道我可以从测试内部抛出一个错误,但我想知道是否有类似 Jasmine 提供的全局 fail() 方法的东西?

【问题讨论】:

    标签: javascript jestjs


    【解决方案1】:

    Jest 实际上使用了 Jasmine,所以你可以像以前一样使用 fail

    示例调用:

    fail('it should not reach here');
    

    这是 Jest 的 TypeScript 声明文件中的定义:

    declare function fail(error?: any): never;
    

    【讨论】:

    • 这是我错过的电话。我的测试用例在我的单元测试中的订阅中失败,而不会导致单元测试失败。使用 try/catch 包装订阅的内容并使用捕获的错误调用 fail(e) 允许测试失败并按预期发送正确的消息。
    【解决方案2】:

    你可以通过抛出一个错误来做到这一点。例如:

    test('Obi-Wan Kenobi', () => {
      throw new Error('I have failed you, Anakin')
    })
    

    【讨论】:

    • OP 说他们知道抛出错误......这并没有按照要求提供新的解决方案。 (即使其他方面都很好。)
    【解决方案3】:

    复制/意大利面测试失败:

    it('This test will fail', done => {
      done.fail(new Error('This is the error'))
    })
    

    【讨论】:

    • 恕我直言,这应该是公认的答案。对于同步测试,您只需使用 fail(new Error('What the fork?'));
    【解决方案4】:

    在某些情况下,某些答案不起作用。在async-await 的世界里,这样的try-catch 逻辑是很常见的。

    try {
      await someOperation();
    } catch (error) {
      expect(error.message).toBe('something');
    }
    

    现在想象一下,如果 someOperation() 以某种方式通过了,但您预计它会失败,那么这个测试仍然会通过,因为它从未进入 catch 块。 所以我们想要的是确保如果 someOperation 没有抛出错误,则测试失败。

    现在让我们看看哪些解决方案有效,哪些无效。

    接受的答案在这里不起作用,因为掷球会再次被接住。

    try {
      await someOperation();
      throw new Error('I have failed you, Anakin');
    } catch (error) {
      console.log('It came here, and so will pass!');
    }
    

    true === false 的答案也行不通,因为断言也会引发类似上述的错误,该错误将被捕获。

    try {
      await someOperation();
      expect(true).toBe(false); // This throws an error which will be catched.
    } catch (error) {
      console.log('It came here, and so will pass!');
    }
    

    对于这种情况,一种可行的解决方案(如@WhatWouldBeCool 的回答所示)如下。现在它明确地没有通过测试。

    try {
      await someOperation();
      fail('It should not have come here!')
    } catch (error) {
      console.log('It never came here!');
    }
    

    【讨论】:

    【解决方案5】:

    不认为有,在这里讨论:https://github.com/facebook/jest/issues/2129

    【讨论】:

      【解决方案6】:

      你总是可以做这样的事情:)

      expect(true).toBe(false);
      

      【讨论】:

      • 不推荐使用这种方法,因为错误消息类似于“预期为真为假”。测试旨在确定性和精确性。虽然从技术上讲这不推荐使用
      【解决方案7】:

      这里有很多好主意。只是为了添加有关测试异步代码的额外信息,这可能会导致尝试使 Jest 显式失败,请查看文档中的 Testing Asynchronous Code https://jestjs.io/docs/en/asynchronous

      要测试返回一个已解析的 Promise 的函数,返回 Promise 很重要,因此 Jest 知道只有在 Promise 已解析或超时时才完成测试:

      test('the data is peanut butter', () => {
        return fetchData().then(data => {
          expect(data).toBe('peanut butter')
        })
      })
      

      要测试返回拒绝的 Promise 的函数,返回 Promise 很重要,因此 Jest 知道只有在 Promise 被拒绝或超时时才进行测试。并且还必须说明 Jest 需要计算多少个断言,否则如果 Promise 被解决,它就不会失败——在这种情况下这是错误的——:

      test('the fetch fails with an error', () => {
        expect.assertions(1)
        return fetchData().catch(e => expect(e).toMatch('some specific error'))
      })
      

      【讨论】:

        【解决方案8】:

        添加 jest-fail-on-console npm 包,然后在您的 jest.config.js 上

        import failOnConsole from 'jest-fail-on-console'
        
        failOnConsole();
        

        一旦由于测试项中抛出错误或警告而由 jest 完成控制台错误或警告,这将导致测试失败。

        【讨论】:

          【解决方案9】:

          您可以抛出一个模拟应用程序抛出的错误的错误,然后期望它的消息与实际不同。

                  try {
                      await somthingYouExpectToFail();
                      throw new Error("Fail!");
                  } catch (error) {
                      expect(error.message).not.toBe("Fail!");
                  }
              
          

          【讨论】:

          • 虽然这段代码 sn-p 可以解决问题,但它没有解释为什么或如何回答这个问题。请include an explanation for your code,因为这确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-11-28
          • 1970-01-01
          • 2020-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多