You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jest正确模拟Web3默认导出的构造函数以返回指定模拟对象?

Solution to Mock Web3 Constructor Correctly

Let's break down why your current setup isn't working first, then fix it:

The Root Cause

When you use new with a constructor function in JavaScript, if the constructor returns a primitive value (like your string 'Hello, world!'), JavaScript ignores that return value and instead returns the newly created instance object. That's why you're seeing mockConstructor {} instead of your expected string—your mock's return value is being discarded automatically.

Since Web3 instances are objects by design, you should mock the constructor to return an object with the properties/methods your tests need. Here's how to adjust your code:

import Web3 from 'web3';

jest.mock('web3', () => {
  // Return a mock constructor that creates our custom instance
  return jest.fn().mockImplementation(() => ({
    // Add any Web3 instance properties/methods your test relies on here
    eth: {
      requestAccounts: jest.fn().mockResolvedValue(['0x1234567890abcdef'])
    },
    // Optional: Add a toString method to mimic your original expected output
    toString: () => 'Hello, world!'
  }));
});

describe('app', () => {
  test('mock web3', () => {
    console.log('web3:', Web3);
    const web3 = new Web3(window.ethereum);
    
    console.log("new web3:", web3); // Logs the custom mock object
    console.log("new web3 as string:", web3.toString()); // Logs 'Hello, world!'
    
    // Verify the constructor was called with the correct argument
    expect(Web3).toHaveBeenCalledWith(window.ethereum);
  });
});

Fix 2: Simulate a "Primitive-like" Instance (Edge Case)

If you absolutely need to mimic a primitive return (though this isn't realistic for actual Web3 usage), you can create an object that behaves like a string:

jest.mock('web3', () => {
  return jest.fn().mockImplementation(() => {
    const mockInstance = Object.create(String.prototype);
    Object.assign(mockInstance, 'Hello, world!');
    return mockInstance;
  });
});

This creates an object that acts like a string (e.g., web3 === 'Hello, world!' will return true) but remains technically an object, which aligns with JavaScript's constructor rules.

Why Your Previous Attempts Didn't Work

  • Moving the import after jest.mock() has no effect because Jest automatically hoists all jest.mock() calls to the top of the module.
  • Switching to require() doesn't change JavaScript's core behavior around constructor return values—primitive returns are still ignored.

内容的提问来源于stack exchange,提问作者lmat - Reinstate Monica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 18:02:33