約束事を持つ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」引数は、、ではない理由を任意のアイデアは?
バグが発生した場合、「サーバー」の値は何が? "$ {BASE_URI}/$ {id}"の値は何ですか? – shaochuancs
@shaochuancs質問に値を表示するコードを追加しました。サーバーはノードhttpサーバーです。私のexpressjs apiのBASE_URIは "/ api/users"で、テストのためにコレクションが移植された後、 "id"はmongodbのドキュメントIDに設定されます。 –