What sone people really love about angular, is its dependency injection feature. You register all classes to the IoC Container and when using a component, Angular will new that class for you, injecting all its dependencies, that have been specified in the constructor to be needed.

In a test, you can create an instance of a component yourself with ‘new’ and provide the original or a mock dependency to it. Thanks to typescript, you always get help to.

Last year microsoft published a dedicated inversion of control container tsyringe. It is dedicates for framework independent node.js and client applications.

And the also the nest.js framework, that introduces a IoC container to node.js.

Best IoC Container in node.js are Modules

When you import or require dependencies, you can directly use then and typescript know what type everything has. This way, it is possible to avoid lots of duplicated type definitions.

Buy in unit test we have to be able to inject a mock as dependency. We need a dependency injection container.

And this is the kicker: the require function is a great dependency injection container. You can overwrite dependencies yourself, or use a little utility module to inject the mock when the module require a module.

For me proxyquire works pretty good. But most people today like the all in one solution jest better. Often I also use sinon. It can quickly mock a single dependency function.

Javascript Module Formats

Today in 2020, a shift in javascript modules is happening. That is why some solution thay did a good job in the past has a difficult time today.

Typescript and JavaScript have now support for the new javascript modules and the import expirt feature. One part of these modules that I really don’t like, is the ‘default export and how how typescript assign this to 'module.exporta.default. Before in node.js we have been able to export like this: module.export = function().... But typescript and the new js modules have a difficult time to use the new ‘import’ feature to import these features.

My advice is that’s why, to always do named exports. That can can work well across all todays environments. Hopefully, the new module format get supported my node.js very soon.

How to use Proxyquire

In your test file, if you are using mocha or any other testing frameworn, you require or import proxyquire. Then you can use it like this:

1
2
3
4
5
6
const moduleToTest = proxyquire.noCallThru().load('../path/to/moduleToTest', {
dependency: {
functionality(){/* ... */}
}
});
// do the test with the module

This example is working proxyquire will behave similar to require. When the moduleToTest is require or import the dependency and the test will use its functionality that is provided in the second parameter. The functionality should have the same signature as the original.

When working with typescript with the import syntax, I found the dependency you pass into proxyquire, needs an extra field __esModule: true.

Provide a mock via spy or fake from sinon

1
2
3
4
5
6
7
8
9
10
const fakeFunctionality = sinon.fake(()=>[someExampleData]);
const moduleToTest = proxyquire.noCallThru().load('../path/to/moduleToTest', {
dependency: {
functionality: fakeFunctionality
}
});
await moduleToTest.processSomeFunction(withArguments);
// check if the fake functionality was used properly
// by checking the calls and arguments that have been recorded by sinon
// fakeFunctionality.getCall(0).args

What other People do

I prefer modules that do one thing well. Other people prefer using jest today. Jest is kind of a combination of different tools: nyc, mocha, chai, sinon and proxyquire. With that I don’t say it depend on all the other modules, but is provides similar functionality from one package, trying to ease some inconsistencies and incompatibilities. Anyway, I believe extra IoC containers are not needed.

Now that you learned something good about testing, are you interested in some accessibility? a11y

Contents
  1. 1. Best IoC Container in node.js are Modules
  2. 2. Javascript Module Formats
  3. 3. How to use Proxyquire
  4. 4. Provide a mock via spy or fake from sinon
  5. 5. What other People do