2015-07-23 21 views
7

Tôi có lớp hàng đợi của người tiêu dùng sau đó chạy đệ quy thông qua lời hứa:số Khẳng định các cuộc gọi đệ quy trong Sinon

"use strict"; 

var queue = require("./queue"), 
    helpers = require("./helpers"), 
    vendors = require("../config/vendors"), 
    queueConf = require("../config/queue"); 

function Consumer() { 
    this.queue = new queue.TaskQueue(); 
    this.currentItem = null; 
    this.port = null; 
    this.payload = null; 
} 

Consumer.prototype.payloadSuccessCb = function (data) { 
    this.payload = data; 
    this.run(); 
}; 

Consumer.prototype.failureCb = function (data) { 
    console.error(data); 
    throw new Error(data); 
    //TODO: Continue queue processing despite the error 
}; 

Consumer.prototype.processItem = function (data) { 
    this.currentItem = data; 
    process.send("Proccess " + process.pid + " is processing item " + this.currentItem); 
    helpers.getPayload(this.currentItem).then(this.payloadSuccessCb, this.failureCb); 
}; 

Consumer.prototype.wait = function() { 
    var self = this; 
    process.send("Proccess " + process.pid + " is waiting for new items"); 
    setTimeout(function() { 
     self.run(); 
    }, queueConf.waitTime); 
}; 

Consumer.prototype.queueSuccessFb = function (data) { 
    console.error("here"); 
    if (data) { 
     this.processItem(data); 
    } else { 
     this.wait(); 
    } 
}; 

Consumer.prototype.run = function() { 
    //this.port = helpers.getVendorPortById(this.currentItem); 
    this.queue.pop().then(this.queueSuccessFb, this.failureCb); 
}; 

exports.Consumer = Consumer; 

tôi đã xác định một thử nghiệm mà về cơ bản sẽ khẳng định rằng công việc đúng đang xảy ra, và rằng người tiêu dùng cuối cùng là xử lý tất cả các nhiệm vụ trong hàng đợi (đây là một thử nghiệm tích hợp làm việc ở phía trước một nhà môi giới Redis thực)

test:

"use strict"; 

var consumer = require("./../../src/consumer"), 
    queue = require("./../../src/queue"), 
    Q = require("Q"), 
    sinon = require("sinon"), 
    assert = require("assert"), 
    queueConf = require("./../../config/queue"), 
    NUM_OF_ITEMS = 5, 
    queueInstance, 
    spy, 
    consumerInstance; 

describe("consumer", function() { 
    beforeEach(function() { 
     queueInstance = new queue.TaskQueue(); 
    }); 


    describe("waiting for tasks while the queue is empty", function() { 
     describe("queue success call back", function() { 
      before(function() { 
       consumerInstance = new consumer.Consumer(); 
       spy = sinon.spy(consumerInstance, "queueSuccessFb"); 
      }); 

      it("should call the success callback once per the defined period", function (done) { 
       consumerInstance.run(); 
       setTimeout(function() { 
        sinon.assert.calledOnce(spy); 
        done(); 
       }, queueConf.waitTime); 
      }); 

      it("should call the success callback twice per the defined period + 1", function (done) { 
       consumerInstance.run(); 
       setTimeout(function() { 
        sinon.assert.calledTwice(spy); 
        done(); 
       }, queueConf.waitTime * 2); 
      }); 
     }); 

     describe("wait function", function() { 
      before(function() { 
       consumerInstance = new consumer.Consumer(); 
       spy = sinon.spy(consumerInstance, "wait"); 
      }); 
     }); 

    }); 

    describe("task handling", function() { 
     beforeEach(function (done) { 
      this.timeout(6000); 
      var i, promises = []; 
      queueInstance = new queue.TaskQueue(); 
      for (i = 1; i <= NUM_OF_ITEMS; i += 1) { 
       promises.push(queueInstance.push(i)); 
      } 
      Q.all(promises).then(function() { 
       done(); 
      }); 

     }); 

     afterEach(function() { 
      queueInstance.empty(); 
     }); 

     describe("sucess callback", function() { 
      before(function() { 
       consumerInstance = new consumer.Consumer(); 
       spy = sinon.spy(consumerInstance, "queueSuccessFb"); 
      }); 
      it("should run all of the available tasks one by one", function (done) { 
       this.timeout(6000); 
       consumerInstance.run(); 
       setTimeout(function() { 
        console.info(spy.callCount); 
        assert(spy.callCount === NUM_OF_ITEMS); 
        done(); 
       }, 2000); 
      }); 
     }); 
    }); 
}); 

My Vấn đề là số lượng cuộc gọi luôn bằng 1. Lúc đầu tôi nghĩ rằng yêu cầu phương thức andCallThrough() là bắt buộc, tương tự như cách thức hoạt động trong Jasmine, nhưng sau đó phát hiện ra rằng hàm thực sự đang được gọi.

Đã thử sử dụng sinon.useFakeTimers() nhưng không hoạt động chút nào (kiểm tra dường như không đợi, thời gian chờ trong lớp người tiêu dùng không được kích hoạt);

Hành vi mong đợi: callCountNUM_OF_ITEMS (qua cuộc gọi đệ quy). Hành vi thực tế: callCount luôn là 1.

Trả lời

1

Xin chào một chút khó hiểu khi lớp hàng đợi của bạn đang làm gì. Nó là một singleton?

Nếu đó là không một đơn người tiêu dùng của bạn được khởi tạo với hàng đợi trống mới đang được xây dựng.

function Consumer() { 
    this.queue = new queue.TaskQueue(); 
    ... 
} 
... 
    describe("success callback", function() { 
     before(function() { 
      consumerInstance = new consumer.Consumer(); 
      spy = sinon.spy(consumerInstance, "queueSuccessFb"); 
     }); 
     .... 

này sẽ không được giống như hàng đợi mà bạn đã tạo trong

describe("task handling", function() { 
    beforeEach(function (done) { 
     ... 
     queueInstance = new queue.TaskQueue(); 
     ... 
    }); 
    ... 

Và như hàng đợi là không cùng spy.callCount !== NUM_OF_ITEMS

Trừ khi tất nhiên đó là một singleton tức là:

new queue.TaskQueue() === new queue.TaskQueue(); 

Đề xuất của tôi là bật TaskQueue được cung cấp cho người xây dựng Người tiêu dùng để bạn biết rằng người tiêu dùng đang hoạt động trên hàng đợi dự kiến ​​

function Consumer(queue) { 
    this.queue = queue; 
    ... 
} 

describe("task handling", function() { 
    beforeEach(function (done) { 
     ... 
     this.queueInstance = new queue.TaskQueue(); 
     ... 
    }); 
    ... 

    describe("success callback", function() { 
     before(function() { 
      consumerInstance = new consumer.Consumer(this.queueInstance); 
      spy = sinon.spy(consumerInstance, "queueSuccessFb"); 
     }); 
     .... 
Các vấn đề liên quan