Skip to content

Jest does not restore mocks on methods inherited from a prototype properly #8625

Closed
@fongandrew

Description

@fongandrew

🐛 Bug Report

When spying on an object or class, it is possible to mock a method that's defined higher up on the prototype chain. But when the original implementation is restored, the parent object's method is assigned to the child's.

To Reproduce

describe("Spying on protoypes", () => {
  const A = { test: () => 1 };

  const B = Object.create(A);

  afterEach(() => {
    jest.restoreAllMocks();
  });

  it("works with B", () => {
    jest.spyOn(B, "test").mockReturnValue(3);
    expect(B.test()).toEqual(3);
  });

  it("works with A", () => {
    jest.spyOn(A, "test").mockReturnValue(2);
    expect(B.test()).toEqual(2); // Fails, equals 1
  });
});

The second test case above fails with the first test case is present, but passes if the first test case does not exist. If you console log / debugger this, you'll see that the first test is adding a new method to B's prototype, and restoreAllMocks "restored" the mock from the first test by assigning A.test to B.test.

Expected behavior

Mock restoration should work regardless of whether the method is defined higher up on the prototype chain or not.

If B.hasOwnProperty('test') is false, when jest.spyOn(B, 'test') is restored, Jest should just delete B.test rather than assign a value that might have existed only on B's prototype.

Link to repl or repo

Example above ☝️but here's a minimum setup with the latest version of Jest if needed: https://github.com/fongandrew/jest-proto-repo. Also includes a repro with an ES6 class inheritance example.

npx envinfo --preset jest

System:
    OS: macOS 10.14.5
    CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
  Binaries:
    Node: 10.1.0 - ~/.nvm/versions/node/v10.1.0/bin/node
    npm: 6.0.1 - ~/.nvm/versions/node/v10.1.0/bin/npm
  npmPackages:
    jest: ^24.8.0 => 24.8.0 

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions