如何在使用proxyquire和mocha进行单元测试时模拟方法调用时模拟时间延迟(超时)?

时间:2018-02-16 08:51:19

标签: node.js mocha proxyquire

使用proxyquire我模拟模块B的方法(在模块A中注入require()),在模块A中测试方法时。模拟(admitad.model.js模块的模拟get_campaigns方法) :



const admitadModelMock = {
      '../services/admitad.model': {
        get_campaigns: (limit, page) => new Promise((resolve, reject) =>
          setTimeout(resolve({campaigns: testData, count: 1000}), 5000)
        ),
      },
    };




测试:



it('shold get all campaigns from Admitad', async function() {
      this.timeout(60000);
      let err, data;
      // mock dependencie (get_campaigns() of module B will be mocked):
      let $serviceStubbed = proxyquire('../services/campaign-sync', admitadModelMock);
      // getAdmitadCampaigns() just calls get_campaigns method of module B
      [err, data] = await to($serviceStubbed.getAdmitadCampaigns(50));
      data.length.should.be.equal(50);
    });




问题是测试通过而没有预期的5秒延迟。

更新

这是有效的:

setTimeout(() => resolve({campaigns: mockedCampaigns, count: 1000}), 2000)

这是我最后的好方法:



// helper to wrap timeout generation
const timer = (data, time) => 
    new Promise((resolve, reject) => 
        setTimeout(() => resolve(data), time)
);

// Factory function to generate mock with data we need
const blacklistedModelMockFactory =
    (onRead = [], onUpdate = 'Ok', onCreate = 'Ok', onDelete = 'Ok') => ({
  '../services/campaigns-blacklist.model': {
    read: () => timer(onRead, 2000),
    update: () => timer(onUpdate, 2000),
    create: () => timer(onCreate, 1000),
    delete: () => timer(onDelete, 1000),
  },
});

......

// Test example
it('should filter Registered and Blacklisted collections', async function() {
this.timeout(60000);
$service.should.have.property('filterRB').a('function');
const sourceRegistered = mockedCampaigns.slice(5, 10);
const sourceBlacklisted = mockedCampaigns.slice(15, 18);
let error, success;
// mock dependencies in tested module with our expected data:
let $serviceStubbed = proxyquire(
    '../services/campaign-sync', Object.assign(
          {}, 
          blacklistedModelMockFactory(sourceBlacklisted), 
          registeredModelMockFactory(sourceRegistered)
    )
);
[error, success] = await to($serviceStubbed.filterRB(mockedCampaigns));
expect(error).to.be.equal(null);
success.filtered.length.should.be.equal(12);
success.blacklisted.length.should.be.equal(3);
success.registered.length.should.be.equal(5);
});




1 个答案:

答案 0 :(得分:2)

setTimeout(resolve({campaigns: testData, count: 1000}), 5000)

以上线路呼叫流程可以解释如下。

let res = resolve({campaigns: testData, count: 1000});
setTimeout(res, 5000);

您不希望如此,是吗: - )

尝试,

setTimeout(() => resolve({ campaigns: testData, count: 1000 }), 5000)

因为它将resolve调用包装在匿名函数中,并将其作为第一个参数传递给setTimeout调用。