解决承诺的Sinon.JS存根返回" {}"

时间:2017-12-30 12:12:59

标签: node.js sinon

我有一个返回promise的Node.js函数。我正在使用Sinon.JS stubs来解决这个承诺。代码中的我的console.log语句显示存根正在运行。但是,返回的是{}而不是Promise解析的内容。

我回顾了其他这些SO帖子,但两者都不是我遇到的问题:

这是功能:

function publishMessage(pubsub, topicName, data) {   
  const topic = pubsub.topic(topicName);   
  const publisher = topic.publisher();

  return publisher.publish(data)
    .then((results) => {
      const messageId = results[0];
      return messageId;
    })
    .catch((error) => {
      console.log('Error ', error);
      return error;
    }); };

以下是测试:

describe('publishMessage', function() {
  describe('Success', function() {
    it('should return the messageId', function(done) {
      var publishMessage = index.__get__('publishMessage');
      var promise = sinon.stub().resolves(['1111']);
      var publisher = {
        publish: promise
      };
      var topic = {
        publisher: sinon.stub().returns(publisher)
      };
      var pubsub = {
        topic: sinon.stub().returns(topic)
      };
      assert.equal('1111', publishMessage(pubsub, 'st', 'ds'));
      assert.isTrue(topic.publisher.calledWith());
      done();
    });
  });
});

当我执行测试时,console.log的输出显示打印出的分辨率值:

  publishMessage
    Success
      1) should return the messageId
1111


  0 passing (256ms)
  1 failing

  1) publishMessage
       Success
         should return the messageId:
     AssertionError: expected '1111' to equal {}
      at Context.<anonymous> (test/index.spec.js:63:14)

2 个答案:

答案 0 :(得分:2)

你不要等待你的承诺得到解决。

尝试

publishMessage(pubsub, 'st', 'ds').then(result => {
  assert.equal('1111', result);
  assert.isTrue(topic.publisher.calledWith());
  done();
}

答案 1 :(得分:2)

我注意到了一些潜在的问题领域。

首先,我不知道index的定义位置,因此我无法确认您期望的功能是否从index.__get__('publishMessage');返回。您可以通过目视检查

的结果来确认返回了正确的功能
publishMessage.toString();

我看到的另一个问题(更可能是你的问题的原因)是你从publishMessage()返回一个Promise,但是将对该函数的调用结果与Promise的值进行比较最终解决。换句话说,您将Promise与String进行比较。除非你的断言库在检查结果之前等待Promise解析(类似于Jasmine),否则你将String与Promise进行比较。要解决这个问题,只需等待Promise解决:

it('should return the messageId', function(done) {
    // Set up the test case by defining publishMessage, etc.

    publishMessage(pubsub, 'st', 'ds').then((result) => {
        assert.equal(result, '1111');
        assert.isTrue(topic.publisher.calledWith());

        done();
    }).catch(done);
}

注意我在Promise上添加了.catch()。这样可以确保在 Promise中抛出的任何错误都会显示相应的错误,而不仅仅是超时错误。

如果你正在使用像Mocha或Karma / Jasmine这样的测试框架,你可以通过直接返回Promise而不是使用done()来改进这一点。根据我的经验,在尝试调试使用Promise的测试用例时,返回Promise会产生更好的堆栈跟踪以及更有用和准确的错误消息。举个例子:

it('should return the messageId', function() {
    // Set up the test case by defining publishMessage, etc.

    return publishMessage(pubsub, 'st', 'ds').then((result) => {
        assert.equal(result, '1111');
        assert.isTrue(topic.publisher.calledWith());
    });
}

请注意,我不再接受测试用例中的参数。在Mocha和Karma中,这就是框架如何确定如何处理测试用例。