Flushing a constructor (or other function) in a Node.js module outside this module

I use Jasmine to write my tests, but I think I would have a problem with any other testing environment. Let's say that we have a foo module with two functions, Bar and Baz , which are constructors (but can only be normal functions):

 var Bar = exports.Bar = function Bar() { this.baz = new Baz(); }; var Baz = exports.Baz = function Baz() { }; 

Now I would like to test Bar , but with a fake Baz implementation:

 var foo = require('foo'); describe("foo.Bar", function() { it("initializes its own Baz", function() { spyOn(foo, 'Baz'); // this replaces foo.Baz with a fake implementation var bar = new foo.Bar(); expect(foo.Baz).toHaveBeenCalled(); }); }); 

The problem is that this test will fail because Bar creates a new Baz using the Baz variable, which cannot be changed externally. The only thing that has been replaced with spyOn() is exports.Baz .

The obvious solution is to write this.baz = new exports.Baz(); but it looks uncomfortable. If I have more functions that I want to use inside my module, I would always have to call them all with the exports. prefix exports. . Is there any other approach here?

+4
source share
1 answer

If you can somehow separate the two classes, for example, allow another implementation of the Baz class for the bar, then I think the best way and you should go for it.


But if you really want to be able to reference exports.Baz as Baz , then there is one way that I could think of using with .

It is said that using with usually bad practice and should be avoided, I would not use it in my own code, but this is one way to solve it and it could even be using legimate if you know what you are doing.

Here he is:

 with(exports) { exports.Bar = function Bar() { console.log('this is bar!'); this.baz = new Baz(); }; exports.Baz = function Baz() { console.log('original baz!'); }; } 

In another module, if you change foo.Baz to something else, the Baz inside foo will also look at it.

I would still recommend finding a way to make these two classes independent of each other, and then you can just provide Bar with any Baz implementation you want.

+1
source

Source: https://habr.com/ru/post/1380800/


All Articles