Setup for multiple test files
Xerillio opened this issue · 4 comments
I started using this library for a single test file using Mocha to run the tests with mocha ./bin/tests/**/*.test.js - all good. Then I wanted to add tests in another file and suddenly I got an error message similar to the one described in #96 :
Cannot read properties of undefined (reading 'filename')
The README suggests putting the rewiring in a common file that all tests can use instead of a per-test-file rewiring, so this was my rewire.ts:
import rewiremock from "rewiremock";
import * as sinon from "sinon";
export const testInputs = new Map<string, any>();
export const testVariables = new Map<string, any>();
rewiremock("azure-pipelines-task-lib")
.with({
getInput: sinon.stub().callsFake((i: string) => testInputs.get(i)),
getInputRequired: sinon.stub().callsFake((i: string) => testInputs.get(i)),
getBoolInput: sinon.stub().callsFake((i: string) => testInputs.get(i)),
getVariable: sinon.stub().callsFake((v: string) => testVariables.get(v))
});
rewiremock.overrideEntryPoint(module); // Removing this line doesn't seem to change anything
rewiremock.enable();
export { rewiremock };This starts failing even if I add a new empty *.test.ts file, while having only one *.test.ts file works fine. Perhaps this is a duplicate of #96, but if not, how is it recommend to set up a test project with multiple test files?
What I have now as a workaround for the above issue:
// inputs.test.ts
describe("Inputs", () => {
before(() => {
rewiremock("azure-pipelines-task-lib")
.with({
getInput: sinon.stub().callsFake((i: string) => testInputs.get(i)),
// ...
});
});
after(() => {
rewiremock.clear();
});
// I'm testing my `Inputs` class
const createSut = async(): Promise<Inputs> => {
rewiremock.enable();
const InputsConstructor = (await import("../src/inputs")).Inputs;
rewiremock.disable();
return new InputsConstructor();
};
beforeEach(() => {
testInputs.clear();
// Set default `testInputs` values...
testInputs.set(fileGlobInput, "test glob");
});
it("should return the specified task inputs", async() => {
const sut = await createSut();
expect(sut.fileGlob).to.equal("test glob");
// ...
});
});This boilerplate with before, after and createSut would be duplicated in each test file.
Cannot read properties of undefined (reading 'filename')
Can you please provide a more complete callstack.
What would change if you do rewiremock.overrideEntryPoint(module); before anything else?
In any case there is no recommendation to extract mocking of one file to a "setup" file, it was only to setup your unique configuration if present.
Would you consider automocking as a solution for azure-pipelines-task-lib?
@theKashey, here's the stacktrace:
TypeError: Cannot read properties of undefined (reading 'filename')
at getModuleName (F:\coding\repos\azure-devops-pr-commentator\node_modules\rewiremock\lib\utils\modules.js:10:24)
at Function.mockLoader [as _load] (F:\coding\repos\azure-devops-pr-commentator\node_modules\rewiremock\lib\executor.js:275:84)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:541:24)
at async importModuleDynamicallyWrapper (node:internal/vm/module:438:15)
at async formattedImport (F:\coding\repos\azure-devops-pr-commentator\node_modules\mocha\lib\nodejs\esm-utils.js:9:14)
at async exports.requireOrImport (F:\coding\repos\azure-devops-pr-commentator\node_modules\mocha\lib\nodejs\esm-utils.js:42:28)
at async exports.loadFilesAsync (F:\coding\repos\azure-devops-pr-commentator\node_modules\mocha\lib\nodejs\esm-utils.js:100:20)
at async singleRun (F:\coding\repos\azure-devops-pr-commentator\node_modules\mocha\lib\cli\run-helpers.js:125:3)
at async exports.handler (F:\coding\repos\azure-devops-pr-commentator\node_modules\mocha\lib\cli\run.js:370:5)
Moving the overrideEntryPoint call up produces a completely identical stacktrace:
import rewiremock from "rewiremock";
import * as sinon from "sinon";
rewiremock.overrideEntryPoint(module);
export const testInputs = new Map<string, any>();
rewiremock("azure-pipelines-task-lib")
.with({
getInput: sinon.stub().callsFake((i: string) => testInputs.get(i)),
getInputRequired: sinon.stub().callsFake((i: string) => testInputs.get(i)),
getBoolInput: sinon.stub().callsFake((i: string) => testInputs.get(i))
});
rewiremock.enable();I'll definitely take a look at automocking, thanks for suggesting that - I found the README a bit overwhelming so I didn't see that option 😅
@theKashey Just to make sure I'm not getting it wrong. If I want to mock a node module it currently doesn't work with automocking because of #121, right? Since it only looks for the __mocks__ folder inside a subfolder of node_modules - at least that's what my attempt at using that approach shows.
🤦 you are absolutely correct