Mohca 测试失败
Mohca testing failure
我需要在 debug = false 时测试 storeDocument 函数,这将调用 createStorageDocument。但是对于我下面的测试代码给出了一个错误 'TypeError: Attempted to wrap undefined property createStorageDocument as function'
我做错了什么?
而且我更喜欢在 createStorageDocument 函数中对 fetch 进行存根而不是 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();
});
});
});
部分问题是 createStorageDocument
returns 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();
});
}
这里我在 fetch
之前插入了 return
,您不再需要 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();
});
});
我所做的是为应该存储文档的函数创建一个存根(不是模拟,那是另一回事),我用普通的旧断言替换了你的断言 assert
包含在 Node 中。并且不要忘记处理测试中的错误(它们仍然会咬你)。
老实说,如果 storeDocument
也返回一个 Promise 而不是必须使用丑陋的回调函数会更好。
我意识到这可能需要吸收很多东西。
我需要在 debug = false 时测试 storeDocument 函数,这将调用 createStorageDocument。但是对于我下面的测试代码给出了一个错误 'TypeError: Attempted to wrap undefined property createStorageDocument as function'
我做错了什么?
而且我更喜欢在 createStorageDocument 函数中对 fetch 进行存根而不是 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();
});
});
});
部分问题是 createStorageDocument
returns 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();
});
}
这里我在 fetch
之前插入了 return
,您不再需要 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();
});
});
我所做的是为应该存储文档的函数创建一个存根(不是模拟,那是另一回事),我用普通的旧断言替换了你的断言 assert
包含在 Node 中。并且不要忘记处理测试中的错误(它们仍然会咬你)。
老实说,如果 storeDocument
也返回一个 Promise 而不是必须使用丑陋的回调函数会更好。
我意识到这可能需要吸收很多东西。