Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

type error when rewire'ing const #196

Open
justinrush opened this issue Dec 25, 2021 · 4 comments
Open

type error when rewire'ing const #196

justinrush opened this issue Dec 25, 2021 · 4 comments

Comments

@justinrush
Copy link

I'm still seeing #144 which has been closed

I'm still seeing this in rewire v6 / jest v27.4.5.

db.js

function connectDB() {
    console.log('in connectdb');
}
module.exports.connectDB = connectDB;

constMod.js

const { connectDB } = require('./db');

function doIt() {
    console.log('no');
    connectDB();
}

constMod.test.js

const rewire = require('rewire');
const db = require('./db');
const constMod = rewire('./constMod');

db.connectDB = jest.fn();

describe('constMod', () => {
    it('mocks connectDb', () => {
        constMod.__set__({
            connectDB: db.connectDB,
        });

        const doIt = constMod.__get__('doIt');
        doIt();
        expect(db.connectDB).toHaveBeenCalled();
    });
});

Output:

-> % npm run jest       

> js-test@1.0.0 jest /js-test
> jest

 FAIL  ./constMod.test.js
  constMod
    ✕ mocks connectDb

  ● constMod › mocks connectDb

    TypeError: Assignment to constant variable.

      at eval (eval at __set__ (constMod.js:72:5), <anonymous>:1:11)
      at Object.__set__ (constMod.js:72:5)
      at Object.<anonymous> (constMod.test.js:9:18)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.247 s, estimated 1 s
Ran all test suites.
@justinrush
Copy link
Author

You can see this in a unit test on the main branch by:

  • adding an export to testLib/someOtherModule.js: exports.meh = () => {return "meh";}
  • import it in testLib/constModule.js: const { meh } = require("./someOtherModule");
  • add this test case to testLib/sharedTestCases.js:
    it("should be possible to re-assign const required methods", function () {
        var test = rewire("./constModule.js");

        test.__set__({meh: () => {return "bleh"; }});
        const val = test.meh();

        expect(val).to.be("bleh");
    });

@georgezlei
Copy link

I have an interesting finding.

If you rewire a js module below, a type error will be thrown saying the constant variable cannot be assigned.

target.js

const a = 1;
a = 2;

function handler() {}

However, a slight change will make the error disappear.

const a = 1;
a = 2;

async function handler() {}

I haven't checked the rewire source yet and have no idea which behaviour is correct. But it seems that the keyword async triggers another parsing system that changes the constant to a normal variable.

@kswanny
Copy link

kswanny commented Jun 16, 2022

@georgezlei + 1 on this, found this out today too. I think the latter is incorrect, becasue it means tests will pass gracefully if you accidently re-assign a const.

@georgezlei
Copy link

Disagree with the conclusion. The constant re-assignment can be easily detected by the lint tool and it doesn't have to be the responsibility of the unit test. On the other hand, enabling constant re-assignment can help to mock the dependencies of the target module. Think of the below example in your target module:

const dep = require('dependency');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants