This article mainly introduces Node. js uses the dependency injection-related issues and solutions, Node. js is a framework that runs JavaScript applications on the server. if you need JavaScript, refer to the recent introduction. I turn to dependency injection to help you understand the simple way to separate code and help you test it. However, the modules in Node. js depend on the system APIs provided by Node, which makes it difficult to determine whether private dependencies are properly used. General dependency injection is difficult to use in this case, but do not give up hope now.
RequireCauses
Node. js can easily import dependencies as needed. It runs well and is easier than AMD-mode loaders such as RequireJS. The problem arises when we simulate those dependencies. If model loading in Node. js is controlled, how can we control the use of pseudo objects during testing? We can use the Node vm mode. through the vm, we can load the model in a new context. Running in the new context, we can control the method of reflecting the model according to the requirement.
Solution
Thanks for this article. now we can provide you with a pretty good solution. the code is as follows:
var vm = require('vm');var fs = require('fs');var path = require('path'); /*** Helper for unit testing:* – load module with mocked dependencies* – allow accessing private state of the module** @param {string} filePath Absolute path to module (file to load)* @param {Object=} mocks Hash of mocked dependencies*/exports.loadModule = function(filePath, mocks) {mocks = mocks || {}; // this is necessary to allow relative path modules within loaded file// i.e. requiring ./some inside file /a/b.js needs to be resolved to /a/somevar resolveModule = function(module) { if (module.charAt(0) !== '.') return module; return path.resolve(path.dirname(filePath), module);}; var exports = {};var context = { require: function(name) { return mocks[name] || require(resolveModule(name)); }, console: console, exports: exports, module: { exports: exports }}; vm.runInNewContext(fs.readFileSync(filePath), context);return context;};
You can also download the code snippet here. although it is not the most widely published code in the article, he can still use some explanations. during the test, we need to load this module to test, and use theloadModulefunction instead of ofrequire to load the module.
The first parameter, filePath, specifies the search location for the model to be tested. The second parameter mocks contains an object. The property name of the object must match the name of the model we tried require. The values specified by these attributes are pseudo objects, which are used to replace the model typically called require.
In essence, vm is used to load and run the model in another "context. In other words, we recreate global variables (such as require and exports) so that we can control them. Note that we have compiled an available New require function. Everything is done to check whether there is a simulated dependency in the name of the execution. if there is a dependency every day, I will delegate it to the commonly used require function.
Example of using the module loader
If you are still confused, you can refer to the following sample code to see its usage in the context. First, create a simple module.
Var fs = require ('Fs'); module. exports = {// Do something with 'Fs'} think this is cool, right? However, now we test that module, but we need to simulate fs to see how it is used internally. // Jasmine's syntax http://pivotal.github.com/jasmine/describe ('somemodule', function () {var loadModule = require ('Module-loader '). loadModule; var module, fsMock; beforeEach (function () {fsMock ={// a mock for 'Fs '}; // load the module with mock fs instead of real fsmodule = loadModule ('. /web-server.js ', {fs: fsMock}); it ('Could work', function () {// a test that utilizes the fact that we can now control 'Fs '});});
The main note is in lines 7 to 12, we created a pseudo object for fs and used our new loadModule function to connect the used object to the small module above (I mean awesome! Remember, this is awesome, right ?).