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?
Wenn Fehler passiert, was ist der Wert von „Server“? Und was ist der Wert von "$ {BASE_URI}/$ {id}' " – shaochuancs
@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. –