嘲笑单元测试以监视较低级别的方法(NodeJS) [英] Jest unit test to spy on lower-level method (NodeJS)

查看:118
本文介绍了嘲笑单元测试以监视较低级别的方法(NodeJS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用Jest侦探和覆盖一个向下两级的功能.

Trying to spy and override a function two levels down using Jest.

测试结果显示,预期已调用模拟函数,但尚未调用."

The test results say, "Expected mock function to have been called, but it was not called."

// mail/index.unit.test.js
import mail from './index';
import * as sib from '../sendinblue';

describe('EMAIL Util', () =>
  test('should call sibSubmit in server/utils/sendinblue/index.js', async() => {
    const sibMock = jest.spyOn(sib, 'sibSubmit');
    sibMock.mockImplementation(() => 'Calling sibSubmit()');
    const testMessage = {
      sender: [{ email: 'foo@example.com', name: 'Something' }],
      to: [{ email: 'foo@example.com', name: 'Something' }],
      subject: 'My Subject',
      htmlContent: 'This is test content'
    };
    await mail.send(testMessage);
    expect(sibMock).toHaveBeenCalled();
  })
);

mail.send()来自这里...

mail.send() comes from here...

// mail/index.js
import { sibSendTransactionalEmail } from '../sendinblue';

export default {
  send: async message => {
    try {
      return await sibSendTransactionalEmail(message);
    } catch(err) {
      console.error(err);
    }
  }
};

哪个通过axios使用SendInBlue的API(为什么我需要模拟)...

Which uses SendInBlue's API via axios (why I need to mock)...

// sendinblue/index.js
import axios from 'axios';
import config from '../../config/environment';

export async function sibSubmit(method, url, data) {
  let instance = axios.create({
    baseURL: 'https://api.sendinblue.com',
    headers: { 'api-key': config.mail.apiKey }
  });
  try {
    const response = await instance({
      method,
      url,
      data
    });
    return response;
  } catch(err) {
    console.error('Error communicating with SendInBlue', instance, err);
  }
}

export const sibSendTransactionalEmail = message => sibSubmit('POST', '/v3/smtp/email', message);

我假设mail.send()将在另一个模块中调用sibSendTransactionalEmail(),并且它将调用sibSubmit(),这是jest.spyOn()的重点.想知道我哪里出了错.

I assumed mail.send() would call sibSendTransactionalEmail() in the other module and it would call sibSubmit(), the focus of jest.spyOn(). Wondering where I went wrong.

推荐答案

jest.spyOn 替换在这种情况下,您传递的sib代表从sendinblue.js导出的ES6模块,因此Jest会将模块导出替换为sibSubmit并提供间谍您提供的模拟实现.

In this case you are passing sib which represents the ES6 module exports from sendinblue.js, so Jest will replace the module export for sibSubmit with the spy and give the spy the mock implementation you provided.

mail.send然后调用sibSendTransactionalEmail ,然后直接调用sibSubmit .

mail.send then calls sibSendTransactionalEmail which then calls sibSubmit directly.

换句话说,不会调用您的间谍,因为sibSendTransactionalEmail不会调用 sibSubmit模块导出,它只是直接调用sibSubmit.

In other words, your spy is not called because sibSendTransactionalEmail does not call the module export for sibSubmit, it is just calling sibSubmit directly.

解决此问题的简单方法是注意"ES6模块自动支持循环依赖" ,因此您可以简单地将模块导入自身并使用模块export从sibSendTransactionalEmail内部调用sibSubmit:

An easy way to resolve this is to note that "ES6 modules support cyclic dependencies automatically" so you can simply import the module into itself and call sibSubmit from within sibSendTransactionalEmail using the module export:

import axios from 'axios';
import config from '../../config/environment';
import * as sib from './';  // import module into itself

export async function sibSubmit(method, url, data) {
  let instance = axios.create({
    baseURL: 'https://api.sendinblue.com',
    headers: { 'api-key': config.mail.apiKey }
  });
  try {
    const response = await instance({
      method,
      url,
      data
    });
    return response;
  } catch(err) {
    console.error('Error communicating with SendInBlue', instance, err);
  }
}

export const sibSendTransactionalEmail = message => sib.sibSubmit('POST', '/v3/smtp/email', message);  // call sibSubmit using the module export

请注意,像这样,用jest.spyOn替换ES6模块导出是可行的,因为Jest将ES6模块转换为以下版本中的Node模块:一种允许他们变异的方式

Note that replacing ES6 module exports with jest.spyOn like this works because Jest transpiles the ES6 modules to Node modules in a way that allows them to be mutated

这篇关于嘲笑单元测试以监视较低级别的方法(NodeJS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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