Reputation: 473
The following has to do with a full stack Node.js problem. It involves Express, Mongoose, and Mocha.
I have a controller module with a function that processes an HTTP call. It basically takes Request and Response objects as its arguments. Within it, it pulls Form data out of the Request object and stores data in multiple MongoDB instances. In order to accomplish multiple data stores we use a call to Promise.all. This is done in an async function. Something like the following
async function saveData(data1 : Data1Interface, data2 : Data2Interface,
res: Response)
{
try
{
//Call 3 save methods each returning promised. Wait fLoginInfoModelor them all to be resolved.
let [data1Handle, data2Handle] = await Promise.all([saveData1(data1),
saveData2(data2)]);
//if we get here all of the promises resolved.
//This data2Handle should be equal to the JSON {"id" : <UUID>}
res.json(data2Handle);
res.status(200);
}
catch(err)
{
console.log("Error saving registration data” + err);
res.json( {
"message" : "Error saving registration data " + err
});
res.status(500);
}
}
Within saveData1 and saveData2 I am doing something like:
function saveData1(data : DataInterface) : Promise<any>
{
let promise = new Promise(function(resolve : bluebird.resolve, reject : bluebird.reject)
{
Data1Model.create(data, function(err,
data){
….
.
.
However I want to test this method using Mocha. This is where the problems start. For the sake of brevity I am only using one of the Mongoose Models in this example. If I try to run the following code as a mocha unit test I get the following error message. I am not sure what it wants as far as a Promise constructor?
TSError: ⨯ Unable to compile TypeScript
Cannot find global value 'Promise'. (2468)
server/controllers/registration.server.controller.ts (128,17): An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your --lib
option. (2705)
server/controllers/registration.server.controller.ts (134,66): 'Promise' only refers to a type, but is being used as a value here. (2693)
Note that line 128 is the line that starts “async function saveData(data1 : Data1Interface, data2 : Data2Interface, res: Response) “
The following two lines “let [data1Handle, data2Handle] = await Promise.all([saveData1(data1), saveData2(data2)]); “ and
“ let promise = new Promise(function(resolve : bluebird.resolve, reject : bluebird.reject)”
produce the “'Promise' only refers to a type, but is being used as a value here.” errors.
The Mocha unit test code looks something like the following.
import 'mocha';
import { expect } from 'chai';
import * as sinon from 'sinon';
var config = require('../config/config');
import * as sinonmongoose from 'sinon-mongoose';
import * as controller from './registration.server.controller';
import { Request, Response } from 'express';
import { Data1Interface, Data1Model} from '../models/data1.server.model';
import * as mathUtilities from '../utilities/math.utilities';
import mongoose = require("mongoose");
import * as bluebird from 'mongoose';
(mongoose as any).Promise = bluebird.Promise;
//NOTE: This currently does not work.
describe('Registration related tests', function () {
beforeEach(()=>{
});
afterEach(()=>{
//sinon.restore(authentication);
});
it('should return 200 OK valid outline', function (done) {
let dummyRequest: any = {
body: {
username: "awhelan",
password: "awhelan",
firstName : "Andrew",
lastName: "Whelan",
email: "[email protected]",
source: "none",
school: "Arizona",
consent: true,
dob: "1970-03-10",
gender:"Male",
interviewconsent: true,
recordingconsent: true
}
};
let id = mathUtilities.createId("Andrew", "Whelan", "[email protected]");
let retJson = "{id:" + id +"}";
let dummyResponse: any = {
json: function (data) {
expect(data).to.equal(retJson);
done();
return this;
},
sendStatus: function (code) {
expect(code).to.equal(200);
done();
return this;
}
};
let req: Request = dummyRequest as Request;
let res: Response = dummyResponse as Response;
let mock = sinon.mock(Data1Model).expects('create').yields(null, { nModified: 1 });
controller.register(req, res);
sinon.restore(Data1Model.create);
});
});
Note that the suggestion in ts An async function or method in ES5/ES3 requires the 'Promise' constructor” doesn’t help.
Any suggestions as to how I might move past these errors would be appreciated.
-Andrew
Upvotes: 2
Views: 3235