开玩笑:嘲笑条件函数调用 [英] Jest: mocking conditional function calls

查看:248
本文介绍了开玩笑:嘲笑条件函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个测试,以确保在适当的情况下,使用特定的消息调用特定的函数(在这种情况下为哨兵函数).但是,当我编写此测试时,它失败了,并且收到以下消息.如何正确模拟handleError.test.js中的captureMessage函数,以确保使用handleError.js中的"this is an error message."字符串正确调用该函数?谢谢!

I am trying to write a test to make sure that, when appropriate, a particular function (in this case, a sentry function) is called with a particular message. However, when I write this test, it fails, and I get the following message. How to I properly mock the captureMessage function in handleError.test.js to make sure that it is properly called with the "this is an error message." string in handleError.js? Thanks!

错误消息:

错误:期望(jest.fn())[.not] .toHaveBeenCalledWith()

Error: expect(jest.fn())[.not].toHaveBeenCalledWith()

jest.fn()值必须是模拟函数或间谍程序.收到:功能: [功能captureMessage]

jest.fn() value must be a mock function or spy. Received: function: [Function captureMessage]

handleError.js:

import {captureMessage} from '@sentry/browser';

const handleError = (error) => {
  if (error.name === "ApiError") {
    captureMessage('this is an error message.');
  }
};

export default handleError;

handleError.test.js:

import {captureMessage} from '@sentry/browser';
import handleError from '../handleError';

class ApiError extends Error {
  constructor() {
    super();
    this.name = 'ApiError';
  }
}

test('When an ApiError is returned with no action type, sentry is notified', () => {
  const sampleError = new ApiError();
  handleError(sampleError);
  expect(captureMessage).toHaveBeenCalledWith('this is an error message.');
});

推荐答案

正如@balzee所述,您实际上必须监视要断言的方法.这导致Jest用特殊的间谍函数替换该方法,该函数跟踪被调用的参数,被调用的次数等等.

As @balzee mentioned, you have to actually spy on the method you want to make assertions about. That causes Jest to replace the method with a special spy function that keeps track of the parameters it is called with, how many times it was called, and so on.

您还应该为该函数提供模拟实现,以免在运行单元测试时实际上不呼唤哨兵.

You should also provide a mock implementation for that function, so that you don't actually call out to Sentry when running your unit tests.

最后,当监视一个方法时,首先传递该方法所在的对象,然后将该方法的名称作为字符串传递.然后,Jest用一个间谍函数替换该对象上的该属性,如果没有给出模拟实现,它将调用原始函数.

Finally, when spying on a method, you first pass the object the method is on, and then the name of the method as a string. Jest then replaces that property on the object with a spy function, that will call the original function if no mock implementation is given.

如果不引用函数所在的对象,则只需将本地函数变量指向的对象从原始/实函数更改为开玩笑的间谍函数即可.那不会改变您正在测试的代码调用的功能,因此测试将失败.

Without referencing the object the function exists on, you would just be changing what a local function variable points to, from the original/real function to a jest spy function. That won't change the function that the code you are testing invokes, so the test will fail.

所以最终的测试应该是:

So the final test should be:

handleError.test.js:

import * as sentry from '@sentry/browser'; // CHANGED
import handleError from '../handleError';

class ApiError extends Error {
  constructor() {
    super();
    this.name = 'ApiError';
  }
}

// added this to remove any spies/mocks after the test
afterEach(() => {
  jest.restoreAllMocks();
});

test('When an ApiError is returned with no action type, sentry is notified', () => {
  const sampleError = new ApiError();
  // added next line
  jest.spyOn(sentry, 'captureMessage').mockImplementation(() => {});
  handleError(sampleError);
  // note the use of `sentry.captureMessage`, which is now a jest spy fn
  expect(sentry.captureMessage).toHaveBeenCalledWith('this is an error message.');
});

这篇关于开玩笑:嘲笑条件函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆