Fixed function instead of function

I have a problem with Sinon to work correctly for me. When I close the list on retro and test runs, app.get('/retro', retro.list) performs the original function retro.list instead of a stub. Since this happens, the test fails because the callCount stub is 0.

I am more familiar with coffeescript, and I also cut through things. Is there something that I don’t understand in the Javascript area, or how require('../routes/retro') works, or retro not the same in app.js and test.js

Thanks so much for the help and code below.

test.js:

 var request = require('supertest') , retro = require('../routes/retro') , app = require('../app') , sinon = require('sinon'); require('should'); describe('GET /retro', function() { // less involved, but maybe stupid to test it('should call retro.list', function(done) { var stub = sinon.stub(retro, 'list'); request(app) .get('/retro') .end(function(err, res){ stub.callCount.should.equal(1); if (err) return done(err); done(); }) }) }) 

app.js:

 var express = require('express') , config = require('./config') , routes = require('./routes') , retro = require('./routes/retro'); var app = express(); config(app); app.get('/', routes.index); app.get('/retro', retro.list); module.exports = app; 

retro.js:

 var retro = { list: function(req, res){ console.log('actual called'); res.send("respond with a resource"); } } module.exports = retro; 
+4
source share
2 answers

You probably need to create your stubs before you require / create an app .

 var request = require('supertest') , sinon = require('sinon') , retro = require('../routes/retro'); var stubRetroList = sinon.stub(retro, 'list'); var app = require('../app'); // ... stubRetroList.callCount.should.equal(1); 

This allows you to update retro.list before it is passed to the route:

 app.get('/retro', retro.list); 

The problem is probably due to the fact that retro.list not passed by reference (pointer), but rather is a link that is passed by value (copied). Thus, although sinon.stub() modifies retro.list , this will not affect the copy that the '/retro' route already had.

+8
source

I ran into the same problem and the accepted answer (albeit true) did not help. It turns out that for sinon to work sinon method cannot be used in one module. In other words, a module endpoint stub will only muffle the module endpoint, not the internal use of the function referenced by module.exports .

Explained with an example:

module.js

 const express = require('express') const router = express.Router() router.get('/', function (req, res) { res.status(200).json(list()) }) function list() { return ['something'] } module.exports = { router: router, list: list } 

module.spec.js

 // This stub will not work sinon.stub(module, 'list').callsFake(() => ['something else']) 

To make it work, you must separate what the stubs want into your own module and use it like this:

sub_module.js

 function list() { return ['something'] } module.exports = { list: list } 

Now sub_module.list() can be stubbed.

(The OP defines the method in place, so this is not a problem for it)

0
source

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


All Articles