Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Jest中测试抛出异常的类型_Javascript_Unit Testing_Jestjs - Fatal编程技术网

Javascript 如何在Jest中测试抛出异常的类型

Javascript 如何在Jest中测试抛出异常的类型,javascript,unit-testing,jestjs,Javascript,Unit Testing,Jestjs,我正在处理一些代码,需要测试函数抛出的异常类型(是TypeError、ReferenceError等吗?) 我当前的测试框架是AVA,我可以将其作为第二个参数t.throws方法进行测试,如下所示: it('should throw Error with message'UNKNOWN Error\'when not params passed',(t)=>{ 常量错误=t.throws(()=>{ 投掷者(); },打字错误); t、 是(error.message,“未知错误”); });

我正在处理一些代码,需要测试函数抛出的异常类型(是TypeError、ReferenceError等吗?)

我当前的测试框架是AVA,我可以将其作为第二个参数
t.throws
方法进行测试,如下所示:

it('should throw Error with message'UNKNOWN Error\'when not params passed',(t)=>{
常量错误=t.throws(()=>{
投掷者();
},打字错误);
t、 是(error.message,“未知错误”);
});

我开始开玩笑地重写我的测试,但找不到如何轻松地做到这一点。甚至可能吗?

我自己也没有尝试过,但我建议使用Jest的断言。所以我想你的例子应该是这样的:

it('should throw Error with message \'UNKNOWN ERROR\' when no parameters were passed', (t) => {
  const error = t.throws(() => {
    throwError();
  }, TypeError);

  expect(t).toThrowError('UNKNOWN ERROR');
  //or
  expect(t).toThrowError(TypeError);
});

同样,我还没有测试它,但我认为它应该可以工作。

Jest有一个方法,
toThrow(error)
,来测试函数在被调用时是否抛出

因此,在你的情况下,你应该这样称呼它:

expect(t).toThrowError(TypeError);

.

开玩笑的是,您必须将函数传递到
expect(function).toThrow()

例如:

test("Test description", () => {
  const t = () => {
    throw new TypeError();
  };
  expect(t).toThrow(TypeError);
});
test("Test description", () => {
  expect(() => {http.get(yourUrl, yourCallbackFn)}).toThrow(TypeError);
});
或者,如果您还想检查错误消息:

test("Test description", () => {
  const t = () => {
    throw new TypeError("UNKNOWN ERROR");
  };
  expect(t).toThrow(TypeError);
  expect(t).toThrow("UNKNOWN ERROR");
});
如果需要测试现有函数是否使用一组参数抛出,则必须将其包装在
expect()
中的匿名函数中

例如:

test("Test description", () => {
  const t = () => {
    throw new TypeError();
  };
  expect(t).toThrow(TypeError);
});
test("Test description", () => {
  expect(() => {http.get(yourUrl, yourCallbackFn)}).toThrow(TypeError);
});

这有点奇怪,但它很有效,而且IMHO可读性很好:

it('should throw Error with message \'UNKNOWN ERROR\' when no parameters were passed', () => {
  try {
      throwError();
      // Fail test if above expression doesn't throw anything.
      expect(true).toBe(false);
  } catch (e) {
      expect(e.message).toBe("UNKNOWN ERROR");
  }
});
Catch
块捕获您的异常,然后您可以对引发的
错误进行测试。奇怪的
expect(真)。toBe(假)错误
不会被抛出,则需要code>才能使测试失败。否则,该行永远无法访问(
Error
应在它们前面引发)

@Kenny Body提出了一个更好的解决方案,如果您使用
expect.assertions()
,它可以提高代码质量:

查看原始答案并提供更多解释:

尝试:

expect(t).rejects.toThrow()

我使用了更简洁的版本:

expect(() => {
  // Code block that should throw error
}).toThrow(TypeError) // Or .toThrow('expectedErrorMessage')

最后,我为我们的测试utils库编写了一个方便的方法

/**
 *  Utility method to test for a specific error class and message in Jest
 * @param {fn, expectedErrorClass, expectedErrorMessage }
 * @example   failTest({
      fn: () => {
        return new MyObject({
          param: 'stuff'
        })
      },
      expectedErrorClass: MyError,
      expectedErrorMessage: 'stuff not yet implemented'
    })
 */
  failTest: ({ fn, expectedErrorClass, expectedErrorMessage }) => {
    try {
      fn()
      expect(true).toBeFalsy()
    } catch (err) {
      let isExpectedErr = err instanceof expectedErrorClass
      expect(isExpectedErr).toBeTruthy()
      expect(err.message).toBe(expectedErrorMessage)
    }
  }
从我对Jest的(尽管有限)接触中,我发现
expect().toThrow()
适用于只测试特定类型抛出的错误:

expect(()=>functionUnderTest()).toThrow(TypeError)

或引发带有特定消息的错误:

expect(()=>functionUnderTest()).toThrow('发生了不好的事情!')

如果你同时尝试这两种方法,你会得到一个假阳性。例如,如果您的代码抛出
RangeError('发生了错误!')
,则此测试将通过:

expect(()=>functionUnderTest()).toThrow(新类型错误('Something bad casted!'))

这表明使用try/catch很接近,但是不要期望true为false以确保catch中的expect断言被命中,而是可以在测试开始时使用
expect.assertions(2)
,其中
2
是预期断言的数量。我觉得这更准确地描述了测试的意图

测试错误类型和消息的完整示例:

describe('functionUnderTest', () => {
    it('should throw a specific type of error.', () => {
        expect.assertions(2);

        try {
            functionUnderTest();
        } catch (error) {
            expect(error).toBeInstanceOf(TypeError);
            expect(error).toHaveProperty('message', 'Something bad happened!');
        }
    });
});

如果
functionUnderTest()
没有抛出错误,将命中断言,但
expect.assertions(2)
将失败,测试将失败。

现代Jest允许您对拒绝的值进行更多检查。例如:

const request=Promise.reject({statusCode:404})
wait expect(request).rejects.toMatchObject({statusCode:500});
将因错误而失败

Error: expect(received).rejects.toMatchObject(expected)

- Expected
+ Received

  Object {
-   "statusCode": 500,
+   "statusCode": 404,
  }
很清楚如何做到这一点。假设我有一个接受两个参数的函数,如果其中一个参数为
null
,它将抛出一个错误

function concatStr(str1, str2) {
  const isStr1 = str1 === null
  const isStr2 = str2 === null
  if(isStr1 || isStr2) {
    throw "Parameters can't be null"
  }
  ... // Continue your code
你的测试

describe("errors", () => {
  it("should error if any is null", () => {
    // Notice that the expect has a function that returns the function under test
    expect(() => concatStr(null, "test")).toThrow()
  })
})

如果您使用的是
Promise
s:

await expect(Promise.reject(new HttpException('Error message', 402)))
  .rejects.toThrowError(HttpException);
此外,我只想强调他的解决方案中涉及“[传递]函数到expect(function).toThrow(blank或type of error)”的部分

说句笑话,当您测试一个应该抛出错误的情况时,在被测试函数的expect()包装中,您需要提供一个额外的arrow函数包装层,以便它工作。即

错误(但大多数人的逻辑方法):

对:

expect(() => { functionUnderTesting(); }).toThrow(ErrorTypeOrErrorMessage);
这很奇怪,但它应该可以使测试成功运行。

签出方法

您必须将代码包装在附加的函数回调中

您应该同时检查:错误消息及其类型

例如:

expect(
()=>{//附加函数换行
yourCodeToTest();
}
).托特罗(
new RangeError('重复的数组值:A')
);
由于额外的回调包装,代码不会立即运行,因此
jest
将能够捕获它

您应该始终检查错误消息,以确保您正在检查正确的
抛出
案例,并且没有收到代码可能抛出的另一个错误


检查错误类型也很好,因此客户端代码可能依赖它。

这是一种非常详细的测试异常的方法,当Jest已经有expect.toThrow()检查异常的方法时:是的,但它只测试类型,不测试消息或其他内容,问题是关于测试消息,而不是类型。哈。我的代码需要测试抛出错误的值,所以我需要实例。我会编写错误的期望,比如
expect('here')。not.toBe('here')只是为了好玩:-)@Valery或:
expect('to be')。不是莎士比亚风格的.toBe('to be')
。失败不需要假断言-你可以简单地使用
fail(…)
:)它不适合这种情况:
jest.spyOn(service,'create').mockImplementation(()=>{throw new Error();})
如果模拟方法
create
不是
async
。为什么
尝试
?没有尝试,但答案。如果这是答案,请详细说明。你在现有答案上添加了什么?我想@Razim是这么说的