问题
I've been unable to get my test jasmine test suite running with webpack 4. After upgrading webpack, I get the following error for almost every test:
Error: <spyOn> : getField is not declared writable or has no setter
This is due to a common pattern we use to create spys for simple functions is:
import * as mod from 'my/module';
//...
const funcSpy = spyOn(mod, 'myFunc');
I've played around with module.rules[].type
but none of the options seem to do the trick.
This webpack GH issue indicates ECMA modules are meant to not be writable which makes sense for the web but is there really no workaround for testing?
Relevant package versions:
"jasmine-core": "2.6.4",
"typescript": "2.5.3",
"webpack": "4.1.1",
"webpack-cli": "^2.0.12",
"karma": "^0.13.22",
"karma-jasmine": "^1.1.0",
"karma-webpack": "^2.0.13",
回答1:
There's spyOnProperty
which allows treating a property as read-only by setting the accessType
argument to 'get'
.
Your setup would then look like
import * as mod from 'my/module';
//...
const funcSpy = jasmine.createSpy('myFunc').and.returnValue('myMockReturnValue');
spyOnProperty(mod, 'myFunc', 'get').and.returnValue(funcSpy);
回答2:
Adding to @Anton Poznyakovskiy's answer:
I've added this TypeScript function to my shared testing module as a convenience:
export const spyOnFunction = <T>(obj: T, func: keyof T) => {
const spy = jasmine.createSpy(func as string);
spyOnProperty(obj, func, 'get').and.returnValue(spy);
return spy;
};
Example usage:
import * as mod from 'my/module';
//...
spyOnFunction(mod, 'myFunc').and.returnValue('myMockReturnValue');
回答3:
There's this GitHub issue where they arrive at the same conclusion; that immutable exports are intended. But user lavelle has a workaround (in this comment) where they've created different webpack configs for test and production code. The test config uses "commonjs"
modules, which seems to have worked for them by not creating getters.
来源:https://stackoverflow.com/questions/49396736/can-webpack-4-modules-be-configured-as-to-allow-jasmine-to-spy-on-their-members