简体   繁体   中英

Returning a sinon stub from a sinon stub

I have problems getting a sinon stub to return/resolve another sinon stub. I am using sinon, chai, chai-as-promised and mocha.

I am performing a number of async tasks in sequence and the code I want to test look something like this:

Terminal.findOneAsync({terminalId: terminalId}).then(function(terminal) {
  terminal.lastSeen = timestamp;
  return terminal.saveit();
}).then(function(terminal) {
 //continue to do other stuff
});

And my attempt at creating stubs for this look like this:

var saveitStub = sinon.stub(Terminal.prototype, 'saveit');
saveitStub.resolves(terminalUpdated);
var findOneStub = sinon.stub(Terminal, 'findOneAsync');
findOneStub.resolves(saveitStub);

The "saveit" method is in the Terminal.prototype which is why I need to stub it there. When I attempt to run this I get the error:

Unhandled rejection TypeError: undefined is not a function

at the line:

return terminal.saveit();

But if I dump the terminal object out in the console it looks fine, just like any other stub object (at least to my simple mind). The stubbed saveit() method can be called "stand alone" in a test. But whenever I return it through chai's "return" or chai-as-promised's "resolve" methods I get this error.

Any idea why this is the case?

This line:

findOneStub.resolves(saveitStub)

Is causing Terminal.findOneAsync to return a stub function, not a Terminal instance. Obviously, the stub function has no property called saveit , even though Terminal.prototype does. Since unknown properties come back as undefined , this winds up with you attempting to invoke undefined as a function.

To make a test like this, you're probably better off constructing an instance of Terminal and stubbing its saveit method. If constructing an instance is too difficult for whatever reason, you can use sinon.createStubInstance . Since I don't know your constructor's signature I'll go ahead and do that as an example:

var terminal = sinon.createStubInstance(Terminal);
var saveitStub = terminal.saveit
saveitstub.resolves(terminalUpdated)
var findOneStub = sinon.stub(Terminal, 'findOneAsync')
findOneStub.resolves(terminal);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM