Jest 中文网

Jest 中文网

  • 中文文档
  • API
  • 帮助
  • Blog
  • GitHub
  • 英文官网

›使用指南

简介

  • 快速入门
  • Using Matchers
  • Testing Asynchronous Code
  • Setup and Teardown
  • Mock Functions
  • Jest Platform
  • Jest Community
  • More Resources

使用指南

  • Snapshot Testing
  • An Async Example
  • Timer Mocks
  • Manual Mocks
  • ES6 Class Mocks
  • Bypassing module mocks
  • ECMAScript Modules
  • Using with webpack
  • Using with puppeteer
  • Using with MongoDB
  • Using with DynamoDB
  • DOM Manipulation
  • Watch Plugins
  • Migrating to Jest
  • Troubleshooting
  • Architecture

框架指南

  • Testing React Apps
  • Testing React Native Apps
  • Testing Web Frameworks

API 手册

  • Globals
  • Expect
  • Mock Functions
  • The Jest Object
  • Configuring Jest
  • Jest CLI Options
  • Environment Variables
  • Code Transformation
Edit

Bypassing module mocks

Jest allows you to mock out whole modules in your tests, which can be useful for testing if your code is calling functions from that module correctly. However, sometimes you may want to use parts of a mocked module in your test file, in which case you want to access the original implementation, rather than a mocked version.

Consider writing a test case for this createUser function:

// createUser.js
import fetch from 'node-fetch';

export const createUser = async () => {
  const response = await fetch('http://website.com/users', {method: 'POST'});
  const userId = await response.text();
  return userId;
};

Your test will want to mock the fetch function so that we can be sure that it gets called without actually making the network request. However, you'll also need to mock the return value of fetch with a Response (wrapped in a Promise), as our function uses it to grab the created user's ID. So you might initially try writing a test like this:

jest.mock('node-fetch');

import fetch, {Response} from 'node-fetch';
import {createUser} from './createUser';

test('createUser calls fetch with the right args and returns the user id', async () => {
  fetch.mockReturnValue(Promise.resolve(new Response('4')));

  const userId = await createUser();

  expect(fetch).toHaveBeenCalledTimes(1);
  expect(fetch).toHaveBeenCalledWith('http://website.com/users', {
    method: 'POST',
  });
  expect(userId).toBe('4');
});

However, if you ran that test you would find that the createUser function would fail, throwing the error: TypeError: response.text is not a function. This is because the Response class you've imported from node-fetch has been mocked (due to the jest.mock call at the top of the test file) so it no longer behaves the way it should.

To get around problems like this, Jest provides the jest.requireActual helper. To make the above test work, make the following change to the imports in the test file:

// BEFORE
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
// AFTER
jest.mock('node-fetch');
import fetch from 'node-fetch';
const {Response} = jest.requireActual('node-fetch');

This allows your test file to import the actual Response object from node-fetch, rather than a mocked version. This means the test will now pass correctly.

← ES6 Class MocksECMAScript Modules →
Jest 中文网
中文文档
快速入门使用指南API 参考手册
社区
Stack OverflowReactifluxTwitter
更多
BlogGitHubStar
友链
Bootstrap中文网ReactNext.jsNuxt.jsBlitz.jsDocusaurusGatsbyWebpackNPMYarn
Facebook Open Source
Copyright © 2020 Facebook Inc.
Jest 项目及相关资源的版权归 Facebook 或项目贡献者所有
Jest 中文文档遵循 MIT 开源协议
京ICP备15031610号-38