Skip to content
This repository was archived by the owner on Nov 4, 2024. It is now read-only.
This repository was archived by the owner on Nov 4, 2024. It is now read-only.

Something is wrong with a cache #805

@theKashey

Description

@theKashey

Derived from #798, #799 and theKashey/rewiremock#83

There is a simple test:

  • A.js <- reexports <- B.js <- reexports <- C.js
  • changing C.js, would change B and A results, which are the same.
// A.js
import B from './B';
export default B;

// B.js
import C from './C';
export default C;

// C.js
export default 42;

Test 1

 const subject = rewiremock.proxy(
      () => require('./A'),
      () => {
        rewiremock(() => require('./B')).with('bar')
      }
    );
    expect(subject.default).to.be.equal('bar')

In this test we are replacing B by "bar". It is working

Test 2

it('mock B', () => {
    const subject = rewiremock.proxy(
      () => require('./B'),
      () => {rewiremock(() => require('./C')).withDefault('baz')}
    );
    expect(subject.default).to.be.equal('baz')
  });

This time test would fail. C would be not mocked, as long as B cache would be reused, so it never gets a change to get mocked - execution enters ESM loader with "B", and exists with a result, never calls Module._load again.

Test 3

Add one more test, between these two

it('mock C', () => {
    const subject = rewiremock.proxy(
      () => require('./A'),
      () => {rewiremock(() => require('./C')).with('bar')}
    );
    expect(subject.default).to.be.equal('bar')
  });

It would fail, but test 2 which would be executed right after it, will pass.

Test 4

  • Keep only Test 2 - green
  • Duplicate it - green
  • Add Test3 - green
  • Add Test1 - the test after Test1 is red
  • replace A.js by module.exports = require('./B'); - all tests are green.

So - there is something like cache poisoning, which take a place after A.js

Add D.js

I've extended chain by D.js, then started modifying the code.

  • A->B(mock) - test ok, following fails
  • A->B->C(mock) - test ok, following fails
  • A->B->C->D(mock) - test ok, following ok. This is beyond my imagination.
  • B->C would crash following A->D.

I've also tried to run rewiremocks tests vs esm and majority failed due to cache related issues.

I've also tried to disable ESM cache, but it has no effect.

Theory

Some parts of rewiremock uses require.cache, while others uses Module._cache. While it's the same for nodejs and webpack, it might not be the case for esm.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions