I'm trying out Squire.js as a dependency loader for RequireJS. Using a totally normal web browser for running unit tests. I want to use store
to get a handle to my mocks. But can't stop Squire loading the actual module.
mock
works fine:
define(['lib/squire'], function (squire) {
var injector = new squire();
injector
.mock('modules/dependency', {
run: function () {
console.log("fake dependency run");
}
})
.require(['modules/module-under-test'], function (module) {
module.run();
});
});
Console output
module under test loaded module-under-test.js:2
module under test run module-under-test.js:5
fake module run module-test.js:8
But when I use store
like this:
define(['lib/squire'], function (squire) {
var injector = new squire();
injector
.store('modules/dependency')
.require(['modules/module-under-test', 'mocks'], function (module, mocks) {
mocks.store["modules/dependency"] = {
run: function () {
console.log("fake dependency run");
}
};
module.run();
});
});
The real one is used and run:
real dependency loaded dependency.js:2
module under test loaded module-under-test.js:2
module under test run module-under-test.js:5
real dependency run dependency.js:5
Squire says on the front page of the docs that this is ok to do. Using latest version of Squire.js from Github, and also latest RequireJS from requirejs.org. What am I doing wrong?
I don't see where you are calling run in the second example but I will assume it is after the assignment to mocks.store["modules/dependency"].
I think the issue here is that you are attempting to stub the entire dependency, rather than just the run method. This approach works in the first case because the dependency has not yet been resolved. In the second case, module-under-test already has its reference to dependency. So replacing the copy that Squire has 'stored' does nothing. I believe the correct manner of using store would be as follows:
mocks.store["modules/dependency"].run = function () {
console.log("fake dependency run");
};
In short, if you want to replace the entire dependency then that is what mock is for. Store only allows you to stub individual properties of the dependency before they are accessed by the code under test. (So if the code under test were to invoke run upon load, rather than when invoked by the test, you would still need to use mock.)
There is an alternative approach, for cases where use-upon-load forces you to use mock yet you only want to stub a few properties on the value that the dependency would otherwise resolve to. First require the dependency at the same time the you require Squire. Stub the methods you need stubbed. Then use mock to have Squire to use your partially stubbed dependency when resolving the dependencies for the module under test. In your case, this would look like:
define(['lib/squire', 'modules/dependency'], function (squire, dep) {
var injector = new squire();
dep.run = function () {
console.log("fake dependency run");
};
injector
.mock('modules/dependency', dep)
.require(['modules/module-under-test'], function (module) {
module.run();
});
});
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