I am attempting to unit test a function using Karma as my test runner, Mocha as my testing framework, Sinon as my mocking/stubbing/spying library, and Chai as my assertion library. I am using Chromium as my headless browser in my Karma configuration.
I am totally baffled, however, as to why I am getting the following error:
TypeError: Cannot redefine property: assign
...when I run npm test on this:
function routeToNewPlace() {
const newLoc = "/accountcenter/content/ac.html";
window.location.assign(newLoc);
}
describe('tests', function() {
before('blah', function() {
beforeEach('test1', function() {
window.onbeforeunload = () => '';
});
});
it('routeToNewPlace should route to new place', function() {
expectedPathname = "/accountcenter/content/ac.html";
routeToNewPlace();
const stub = sinon.stub(window.location, 'assign');
assert.equal(true, stub.withArgs(expectedUrl).calledOnce);
stub.restore();
});
});
As you can see, I am attempting to assign an empty string to window.location, but this doesn't seem to help.
Here is my karma.config.js:
module.exports = function(config) {
config.set({
frameworks: ['mocha', 'chai', 'sinon'],
files: ['jstests/**/*.js'],
reporters: ['progress'],
port: 9876, // karma web server port
colors: true,
logLevel: config.LOG_INFO,
//browsers: ['Chrome', 'ChromeHeadless', 'MyHeadlessChrome'],
browsers: ['ChromeHeadless'],
customLaunchers: {
MyHeadlessChrome: {
base: 'ChromeHeadless',
flags: ['--disable-translate', '--disable-extensions', '--remote-debugging-port=9223']
}
},
autoWatch: false,
// singleRun: false, // Karma captures browsers, runs the tests and exits
concurrency: Infinity
})
}
Any thoughts would be greatly appreciated.
The problem you are seeing is that window.location.assign
is a native function that is non-writable and non-configurable. See the discussion of property descriptors on MDN.
See this screenshot and it may help you understand:
What this means is that sinon cannot spy on the assign
function since it cannot overwrite its property descriptor.
The simplest solution is to wrap all calls to window.location.assign
into one of your own methods, like this:
function assignLocation(url) {
window.location.assign(url);
}
And then in your tests, you can do:
const stub = sinon.stub(window, 'assignLocation');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With