2016-09-22 3 views
1

Ich versuche, das Chai-HTTP-Plugin mit Versprechen (mit q) zu verwenden. Ich verwende TypeScript für das Projekt.Chai-http mit Versprechen hat keine Statuseigenschaft

/test/users.ts:

import "mocha"; 
import { Collection } from "mongodb"; 
import { Server } from "../app"; 
import { IUser } from "../interfaces/user"; 
import { IUserModel, User } from "../schemas/user"; 

//use q promises 
global.Promise = require("q"); 

//import mongoose 
import mongoose = require("mongoose"); 

//require http server 
var http = require("http"); 

//require chai and use should assertions 
let chai = require("chai"); 
let expect = chai.expect; 
chai.should(); 

//configure chai-http 
chai.use(require("chai-http")); 

//create http server 
var port = 8080; 
var app = Server.bootstrap().app; 
app.set("port", port); 
var server = http.createServer(app); 
server.listen(port); 

//parent block 
describe("UserApi", function() { 
    const BASE_URI: string = "/api/users"; 
    const COLLECTION_NAME: string = "user"; 
    var id: string; 

    before(function(done: MochaDone) { 
    //empty database 
    if (collectionExists(COLLECTION_NAME)) { 
     User.remove({}).catch(function(result: any) { 
     done(result); 
     }); 
    } 

    //create a user 
    console.log("Creating a new user."); 
    var data: IUser = { 
     firstName: "Brian", 
     lastName: "Love", 
     email: "[email protected]" 
    }; 
    new User(data).save().then(function(user: any) { 
     User.findOne(data).then(function(user: IUserModel) { 
     id = user.id; 
     done(); 
     }).catch(function(result: any) { 
     done(result); 
     }); 
    }).catch(function(result: any) { 
     done(result); 
    }); 
    }); 

    describe("/GET user", function() { 
    it("it should get a user", function() { 
     return chai 
     .request(server) 
     .get(`${BASE_URI}/${id}`) 
     .then(function(res: any) { 
      //this does not work: 
      expect(res).to.have.status(200); 

      //this does not work either: 
      //res.should.have.status(200); 
     }); 
    }); 
    }); 
}); 

function collectionExists(collectionName: string) { 
    return mongoose.connection.on("open", function() { 
    return mongoose.connection.db.listCollections({name: collectionName}).toArray().then(function(items: Collection[]) { 
     return (items.length > 0); 
    }); 
    }); 
} 

Der Express-Server in /app.ts erstellt:

//import modules 
import * as bodyParser from "body-parser"; 
import * as cookieParser from "cookie-parser"; 
import * as express from "express"; 
import * as http from "http"; 
import * as logger from "morgan"; 
import * as path from "path"; 
import * as expressSession from "express-session"; 
import * as url from "url"; 
import errorHandler = require("errorhandler"); 
import flash = require("connect-flash"); 
import methodOverride = require("method-override"); 
import passport = require("passport"); 

//import mongoose 
import mongoose = require("mongoose"); 

//import config 
import { ConfigurationFactory } from "./config/factory"; 
import { IConfiguration } from "./config/config"; 


/** 
* The server. 
* 
* @class Server 
*/ 
export class Server { 

    public app: express.Application; 

    /** 
    * Bootstrap the application. 
    * 
    * @class Server 
    * @method bootstrap 
    * @static 
    * @return {ng.auto.IInjectorService} Returns the newly created injector for this app. 
    */ 
    public static bootstrap(): Server { 
    return new Server(); 
    } 

    /** 
    * Constructor. 
    * 
    * @class Server 
    * @constructor 
    */ 
    constructor() { 
    //create expressjs application 
    this.app = express(); 

    //configure application 
    this.config(); 

    //add routes 
    this.routes(); 

    //add api 
    this.api(); 
    } 

    public api() { 
    //code ommitted 
    } 

    /** 
    * Configure application 
    * 
    * @class Server 
    * @method config 
    * @return void 
    */ 
    public config() { 
    //get configuration 
    let configuration: IConfiguration = ConfigurationFactory.config(); 
    console.log(`[Server.config] Environment: ${configuration.toString()}`); 

    //configure jade 
    this.app.set("views", path.join(__dirname, "views")); 
    this.app.set("view engine", "jade"); 

    //mount logger 
    this.app.use(logger("dev")); 

    //mount json form parser 
    this.app.use(bodyParser.json()); 

    //mount query string parser 
    this.app.use(bodyParser.urlencoded({ 
     extended: true 
    })); 

    //mount cookie parker 
    this.app.use(cookieParser()); 

    //mount override 
    this.app.use(methodOverride()); 

    //add static paths 
    this.app.use(express.static(path.join(__dirname, "public"))); 

    //connect to mongoose 
    mongoose.connect(configuration.db.mongodb).catch(error => new Error(error.message)); 

    //use q library for mongoose promise 
    mongoose.Promise = require("q").Promise; 

    // catch 404 and forward to error handler 
    this.app.use(function(err: any, req: express.Request, res: express.Response, next: express.NextFunction) { 
     err.status = 404; 
     next(err); 
    }); 

    //error handling 
    if (configuration.isDevelopment() || configuration.isTest()) { 
     this.app.use(errorHandler()); 
    } else if (configuration.isProduction()) { 
     this.app.use(function(err: any, req: express.Request, res: express.Response, next: express.NextFunction) { 
     //set status 
     var status: number = err.status || 500; 
     res.status(status); 

     //render error 
     res.render("error", { 
      message: err.message, 
      error: err 
     }); 
     }); 
    } 
    } 

    /** 
    * Create and return Router. 
    * 
    * @class Server 
    * @method config 
    * @return void 
    */ 
    private routes() { 
    //code ommitted 
    } 
} 

habe ich versucht, beide erwarten zu verwenden und Stile Geltendmachung sollte, aber ich Erhalte einen Fehler, der darauf hinweist, dass das Ergebnis keine Eigenschaft "status" hat. Die Überprüfung Res zeigt an, dass tatsächlich keine Statuseigenschaft vorhanden ist. Ich konnte einen Breakpoint in der .then() anonymen Funktion setzen. Hier ist ein Screenshot zeigt die res Variable: Screenshot of VS Code debug

Die Ausnahme vom Laufen des Mokka-Tests:

1) UserApi /GET user it should get a user:                           
    AssertionError: expected [Function] to have a property 'status'                     
    at Assertion.<anonymous> (node_modules/chai-http/lib/http.js:80:38)                    
    at Assertion.ctx.(anonymous function) [as status] (node_modules/chai/lib/chai/utils/addMethod.js:41:25)           
    at dist/test/users.js:49:37                              
    at _fulfilled (node_modules/q/q.js:834:54)                          
    at self.promiseDispatch.done (node_modules/q/q.js:863:30)                      
    at Promise.promise.promiseDispatch (node_modules/q/q.js:796:13)                     
    at node_modules/q/q.js:857:14                             
    at runSingle (node_modules/q/q.js:137:13)                          
    at flush (node_modules/q/q.js:125:13) 

Ich würde es vorziehen, die Versprechen Ansatz zu verwenden. Ich überprüfte die DefinitelyTyped-Definitionsdatei und die then() -Methode sollte mit dem ersten Argument vom Typ ChaiHttp.Response aufgerufen werden. Das Antwortobjekt sollte 3 Eigenschaften hat:

interface Response { 
    body: any; 
    type: string; 
    status: number; 
} 

Irgendwelche Ideen, warum mein „res“ Argument, das ein ChaiHttp.Response Objekt sein soll, ist es nicht?

+0

Wenn Fehler passiert, was ist der Wert von „Server“? Und was ist der Wert von "$ {BASE_URI}/$ {id}' " – shaochuancs

+0

@schaochuancs Ich fügte der Frage mehr Code hinzu, um die Werte anzuzeigen. Der Server ist ein Knoten-HTTP-Server. BASE_URI ist "/ api/users" für meine expressjs api und "id" wird auf die Dokument-ID in mongodb gesetzt, nachdem die Sammlung für den Test ausgefüllt wurde. –

Antwort

1

Ich habe das Problem herausgefunden. Ich verwende die q-Bibliothek für Versprechen in Mungo und ich habe es nicht richtig eingerichtet. Nachdem ich die Dokumentation noch einmal gelesen hatte, erkannte ich, dass Sie auf die statische Eigenschaft .Promise verweisen müssen. Es hat lange gedauert, das herauszufinden, also hoffe ich, dass dies dazu beiträgt, dass jemand das gleiche Problem hat. Hier

ist der Code für richtig q für Versprechen in Mungo mit:

//use q promises 
global.Promise = require("q").Promise; 

//import mongoose 
import mongoose = require("mongoose"); 

//use q library for mongoose promise 
mongoose.Promise = global.Promise;