2016-09-22 11 views
1

約束事を持つchai-httpプラグインを使用しようとしています(qを使用)。私はプロジェクトにTypeScriptを使用しています。約束を使用しているchai-httpにはステータスプロパティがありません

/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); 
    }); 
    }); 
} 

特急サーバーが/app.tsに作成されます。

//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 
    } 
} 

私は期待してスタイルをアサーションする必要がありますが、私の両方を使用しようとしました結果に "status"プロパティがないことを示すエラーを取得します。検査resは、実際にステータスプロパティがないことを示します。私は.then()匿名関数にブレークポイントを設定することができました。ここでは、可変解像度を示すスクリーンショットである:モカテストを実行しているからScreenshot of VS Code debug

例外は次のとおりです。

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) 

私は約束のアプローチを使用することを好むだろう。私はDefinitelyTyped定義ファイルをチェックし、then()メソッドはChaiHttp.Response型の最初の引数で呼び出す必要があります。レスポンスオブジェクトには、3つのプロパティを持っている必要があります。

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

ChaiHttp.Responseオブジェクトである必要があり、私の「RES」引数は、、ではない理由を任意のアイデアは?

+0

バグが発生した場合、「サーバー」の値は何が? "$ {BASE_URI}/$ {id}"の値は何ですか? – shaochuancs

+0

@shaochuancs質問に値を表示するコードを追加しました。サーバーはノードhttpサーバーです。私のexpressjs apiのBASE_URIは "/ api/users"で、テストのためにコレクションが移植された後、 "id"はmongodbのドキュメントIDに設定されます。 –

答えて

1

私は問題を把握しました。私はmongooseの約束のためにqライブラリを使用しており、私はこれを適切に設定していませんでした。ドキュメントをもう少し読んだら、.Promise静的プロパティを参照する必要があることに気付きました。これを見つけるまでには長い時間がかかりましたので、これが誰かに同じ問題を救うのに役立つことを願っています。

ここで適切にマングースにおける約束のためのqを使用するためのコードです:

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

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

//use q library for mongoose promise 
mongoose.Promise = global.Promise; 
関連する問題