0

我需要在 debug = false 时测试 storeDocument 函数,该函数将调用 createStorageDocument。但是对于我下面的测试代码给出了一个错误'TypeError: Attempted to wrap undefined property createStorageDocument as function'

我究竟做错了什么 ?

而且我更喜欢在 createStorageDocument 函数中存根提取的解决方案,而不是 createStorageDocument 本身,有人可以解释一下怎么做吗?我对 mocha 和 node.js 很陌生

import fetch from 'node-fetch';
import documentStorageResponseMock from '../../../test/mock/documentStorageResponseMock';

const storageGatewayUrl = 'url';
const storageGatewayApiKey = 'key';

/**
 * Merge storage id into booking response.
 *
 * @param booking
 * @param documentId
 * @returns {*}
 */
function mergeDocumentId(booking, documentId) {
  const mergedBooking = booking;

  mergedBooking.successfulBooking.documentId = documentId.id;

  return mergedBooking;
}

/**
 * @param labelledBooking
 */
function createStorageDocument(labelledBooking) {
  fetch(storageGatewayUrl,
    {
      method: 'POST',
      body: {
        document: labelledBooking,
      },
      headers: {
        ContentType: 'application/json',
        'x-api-key': storageGatewayApiKey,
      },
    })
    .then((response) => {
      if (response.ok === false) {
        throw new Error('Failed to create the document!');
      } else {
        return response.json();
      }
    }).catch((err) => {
      throw err;
    });
}

/**
 * Save booking response and add the document id to the response.
 *
 * @param labelledBooking
 * @param debug
 * @param callback
 */
export default function storeDocument(labelledBooking, debug = false, callback) {
  if (debug) {
    callback(
      null,
      mergeDocumentId(labelledBooking, documentStorageResponseMock())
    );
    return;
  }

  callback(null, mergeDocumentId(labelledBooking, createStorageDocument(labelledBooking)));
}

import storeDocument from '../../../lib/documents/storeDocument';

const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');

chai.use(require('dirty-chai'));
chai.use(require('chai-fuzzy'));

describe('merge document storage id', function () {
 
  before(function(callback) {
    sinon.stub(storeDocument, 'createStorageDocument', function (params, callback) {
      return ({id: '1087449a-1248-4430-9bcb-5a61b2766020'})
    });
  });

  it('it creates and appends document id to booking when storage gateway is provided ', function(done) {
    storeDocument({
        integrationId: 'testing',
        successfulBooking: {
          integrationServiceId: 'service-id',
          bookingReference: '#ref',
          shippingTaxInclusiveCharge: { amount: 10, currency: 'EUR' },
          pricedAt: '2016-05-20T15:00:00Z',
          documentation: {
            labelDocument: 'ero32ukj32hr3h'
          }
        }
      },
      false,
      (error, booking) => {
        expect(booking.successfulBooking.bookingReference === '#ref').to.be.true;
        expect(booking.successfulBooking.documentation !== undefined).to.be.true;
        expect(booking.successfulBooking.documentId !== '').to.be.true;
        done();
      });
  });
});

4

1 回答 1

1

部分问题是createStorageDocument返回 a Promise,而不是标量值。首先我会重新设计storeDocument.

/**
 * Save booking response and add the document id to the response.
 *
 * @param            labelledBooking
 * @param {Function} createStorageDocument
 * @param {Function} callback
 */
export default function storeDocument(labelledBooking, 
    createStorageDocument,
    callback) {
  createStorageDocument(labelledBooking)
    .then(function (documentId) {
        callback(null, mergeDocumentId(labelledBooking, documentId));
    })
    .catch(callback);
}

好的,这里发生的是我们正在使用依赖注入来注入将存储对象的对象,并且我们正在正确处理 Promise。

然后你想修复createStorageDocument

export function createStorageDocument(labelledBooking) {
  return fetch(storageGatewayUrl, {
      method: 'POST',
      body: {
        document: labelledBooking,
      },
      headers: {
        ContentType: 'application/json',
        'x-api-key': storageGatewayApiKey,
      },
    })
    .then((response) => {
      if (response.ok === false) {
        throw new Error('Failed to create the document!');
      }

      return response.json();
    });
}

在这里我之前插入returnfetch,你不再需要 catch 了(它无论如何都不会工作)。我已将其导出,因此您必须在实际实现中使用它。

好的,现在开始测试。你不需要 Chai - 它只是复杂的事情。谨慎使用 Sinon,并且仅在您更了解 Node 时才使用。你的测试可以变成这样:

  it('it creates and appends document id to booking when storage gateway is provided ', function(done) {
      let createStorageDocumentStub = function (labelledBooking) {
          return Promise.resolve('documentId???')
      }
    storeDocument({
        integrationId: 'testing',
        successfulBooking: {
          integrationServiceId: 'service-id',
          bookingReference: '#ref',
          shippingTaxInclusiveCharge: { amount: 10, currency: 'EUR' },
          pricedAt: '2016-05-20T15:00:00Z',
          documentation: {
            labelDocument: 'ero32ukj32hr3h'
          }
        }
      },
      createStorageDocumentStub,
      (error, booking) => {
        if (error) {
          return done(error);
        }
        assert(booking.successfulBooking.bookingReference === '#ref'));
        assert(booking.successfulBooking.documentation !== void 0);
        assert(booking.successfulBooking.documentId !== '');
        done();
      });
  });

我所做的是为应该存储文档的函数创建一个存根(不是模拟,那是另一回事),并且我已经用 Node.jsassert中包含的普通旧断言替换了您的断言。并且不要忘记处理测试中的错误(它们仍然会咬你)。

不过老实说,如果storeDocument也返回一个 Promise 而不是必须使用丑陋的回调函数会更好。

我意识到这可能需要接受很多。

于 2016-06-08T09:23:43.590 回答