sinon存根不能在nodejstesting中工作

我正在编写Invoicer模块的testing。

我的testing有两个问题。 第一个是邮件仍然被发送,尽pipe已经emailjs模块(第一次testing),第二个问题是我的第二次testing超时后2secs。

我不明白为什么?

有谁能帮我解决这个问题吗?

Invoicer

 'use strict'; var fs = require('fs'); var _ = require('underscore'); var request = require("request"); var email = require("emailjs"); exports.Invoicer = function (url, context) { // set-up our transporter object with credentials var transporter = email.server.connect({ user: 'Pinoquio', password: 'sdlfkjlj', host: "pinoquio@gmail.com", port: 444, tls: true }); // read html file for email fs.readFile('./email.html', function(error, data){ if (error) { context.done(new Error("There was an error reading the file ---> %s", error.message)); } data = data.toString(); var template = _.template(data); // request data from url request(url, function (error, response, body) { if(error) { context.done(new Error("There was an error with request --> %s", error.message)); } if (!error && response.statusCode == 200) { if(typeof body === "string") { var _body = JSON.parse(body); } var populated_html = template(_body); var mailOptions = { text: populated_html, from: 'hick <hick@beta.hick.com>', // sender address to: '<mario@hick.com>', // recipient subject: 'Invoice' } transporter.send(mailOptions, function(error, message){ if(error){ context.done(new Error("There was an error sending the email: %s", error.message)); }else{ context.done(); } }); } }); }); }; 

Tests

 var chai = require('chai'); var sinonChai = require("sinon-chai"); var sinon = require('sinon'); chai.use(sinonChai); var proxyquire = require('proxyquire'); var testedModule; var fs = require('fs'); var email = require('emailjs').server.connect(); var expect = chai.expect; describe('invoicer successful process', function () { var nock = require('nock'); var ResponseOptions = { username: "Peter Pan", user_address_line_1: "Never Never Land", user_address_line_2: "Tree-house 99", user_post_code: "E4 9BY", delivery_address_line_1: "Hook's Boat", delivery_address_line_2: "Dock 69", delivery_post_code: "SE2 4C", order_number: "234234234", order_date: "20/12/2090", dispatch_date: "20/12/2090", items: [ { product_name: "Fairy Dust", brand: "Airy fairy", quantity: 5, total: 2000 }, { product_name: "Pirate Sword", brand: "Pirate's Bay", quantity: 8, total: 2000 } ], grand_total: 4000, user_email: "peter@flyaway.com" } var mailOptions = { text: "Hello World", from: 'hick <hick@beta.hick.com>', // sender address to: '<mario@hick.com>', // recipient subject: 'Invoice' } var scope = nock("http://beta.hick.com") .get("/orders") .reply(200, ResponseOptions); var sendMailStub, readFileStub, url, contextDoneSpy, server; before(function () { server = sinon.fakeServer.create(); server.autoRespond = true; sendMailStub = sinon.stub(email, "send"); readFileStub = sinon.stub(fs, 'readFile'); testedModule = proxyquire('../index.js', { fs: {readFile: readFileStub}, email: {send: sendMailStub} }); url = "http://beta.hick.com/orders"; contextDoneSpy = sinon.spy(); readFileStub.withArgs('./email.html').callsArgWith(1, null, 'file1'); sendMailStub.withArgs(mailOptions).yields(null, contextDoneSpy); }); after(function () { fs.readFile.restore(); email.send.restore(); server.restore(); }); it("readFile and successful context.done were called", function (done) { testedModule.Invoicer(url, { done: function () { contextDoneSpy.apply(null, arguments); expect(readFileStub).has.been.called; expect(contextDoneSpy).to.have.been.calledWithExactly(); done(); }}); }); }); describe("fs.readFile", function () { var readFileStub, url, contextDoneSpy, server; before(function () { server = sinon.fakeServer.create(); server.autoRespond = true; readFileStub = sinon.stub(fs, 'readFile'); testedModule = proxyquire('../index.js', { fs: {readFile: readFileStub} }); url = "http://beta.hick.com/orders"; contextDoneSpy = sinon.spy(); readFileStub.withArgs("Hello world").callsArgWith(1, new Error("Error reading file"), null); }); after(function () { fs.readFile.restore(); server.restore(); }); it("returns error", function (done) { testedModule.Invoicer(url, { done: function () { contextDoneSpy.apply(null, arguments); expect(contextDoneSpy).has.been.called.and.calledWith(new Error("Error reading file")); done(); }}); }); }); 

我设法解决第二个问题首先通过放置returncontext.done(new Error....)

fs.readFile('./ email.html',函数(错误,数据){

 if (error) { context.done(new Error("There was an error reading the file ---> %s", error.message)); return; } 

并在我的testing中传入一个有效的文件名,而不是一个随机string:

  readFileStub.withArgs("./email.html").callsArgWith(1, new Error("Error reading file"), null); }); after(function () { fs.readFile.restore(); });