neo*_*pir 2 mocha.js node.js express supertest
作为一个学习练习,我正在尝试使用Node和Express运行一个版本的Bowling Game kata,我看到了一个奇怪的问题.我可以使用一些帮助来理解为什么来自比我更了解Node和Express的人.
在尝试使攻击测试用例工作的同时编写攻击测试用例之后,当我尝试在命令行使用mocha运行以下测试时,我得到以下超级错误:"Uncaught TypeError: undefined is not a function" at /Users/cdurfee/bitbucket/neontapir/node_modules/supertest/lib/test.js:125:21
.
但是,如果我在game.js(total += rolls[ball + 2];
)中注释掉这个看似无关紧要的行,就没有失败,但当然行为是错误的.我怀疑这是一个数组出界问题,但我不知道一个很好的方法来解决这个问题.
这是两个文件的全部内容和mocha的控制台输出.
08:55 $ mocha --reporter spec
Scoring a bowling game
gutter game
? should return 0
single pin game
? should return 20
spare
? should return 16 after spare and a 3
strike
? should return 24 after strike, 4 and a 3
1) should return 24 after strike, 4 and a 3
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
double callback!
perfect game
4 passing (71ms)
1 failing
1) Scoring a bowling game strike should return 24 after strike, 4 and a 3:
Uncaught TypeError: undefined is not a function
at /Users/cdurfee/bitbucket/neontapir/node_modules/supertest/lib/test.js:125:21
at Test.Request.callback (/Users/cdurfee/bitbucket/neontapir/node_modules/supertest/node_modules/superagent/lib/node/index.js:660:30)
at ClientRequest.<anonymous> (/Users/cdurfee/bitbucket/neontapir/node_modules/supertest/node_modules/superagent/lib/node/index.js:628:10)
at ClientRequest.EventEmitter.emit (events.js:95:17)
at Socket.socketErrorListener (http.js:1547:9)
at Socket.EventEmitter.emit (events.js:95:17)
at net.js:441:14
at process._tickCallback (node.js:415:13)
Run Code Online (Sandbox Code Playgroud)
game.js
var express = require('express');
var app = exports.app = express();
app.get('/start', function(req, res) {
rolls = new Array();
attempt = 0;
});
app.post('/bowl/:pins', function(req, res) {
rolls[attempt] = parseInt(req.params.pins);
attempt++;
});
app.get('/score', function(req, res) {
var total = 0;
var ball = 0;
for (var frame = 0; frame < 10; frame++) {
if (rolls[ball] + rolls[ball + 1] == 10) {
total += rolls[ball + 2]; // this line causes the double callback
}
total += rolls[ball] + rolls[ball + 1];
ball += 2;
}
res.send(200, {score: total});
});
app.listen(process.env.PORT || 3000);
Run Code Online (Sandbox Code Playgroud)
测试/ test.js
var request = require('supertest'),
should = require('should');
var game = require('../game.js').app;
var assertScoreEquals = function(expectedScore) {
request(game).get('/score').expect(200).end(function(err,res) {
should.not.exist(err);
result = res.body;
result.should.have.property('score').eql(expectedScore);
});
};
var roll = function(pins) {
request(game).post('/bowl/' + pins).end();
};
var rollMany = function(times, pins) {
for (var i = 0; i < times; i++) {
roll(pins);
}
};
describe('Scoring a bowling game', function() {
beforeEach(function() {
request(game).get('/start').end();
});
describe('gutter game', function() {
it('should return 0', function() {
rollMany(20,0);
assertScoreEquals(0);
});
});
describe('single pin game', function() {
it('should return 20', function() {
rollMany(20,1);
assertScoreEquals(20);
});
});
describe('spare', function() {
it('should return 16 after spare and a 3', function() {
roll(6);
roll(4); // spare
roll(3);
rollMany(17,0);
assertScoreEquals(16);
});
});
// not expected to pass at the moment
describe('strike', function() {
it('should return 24 after strike, 4 and a 3', function() {
roll(10); // strike
roll(4);
roll(3);
rollMany(17,0);
assertScoreEquals(24);
});
});
// not expected to pass at the moment
describe('perfect game', function() {
it('should return 300', function() {
rollMany(12,10);
assertScoreEquals(300);
});
});
});
Run Code Online (Sandbox Code Playgroud)
添加到我以前的评论
我也看到你的测试用例不是异步的,这几乎肯定是你的问题.
你应该有一个回调: done
describe('gutter game', function() {
it('should return 0', function(done) { // callback is provided as argument by mocha
rollMany(20,0);
assertScoreEquals(0);
done(); // This needs to be called when the test is finished, for async operations.
});
});
Run Code Online (Sandbox Code Playgroud)
我建议也许使用supertest-as-promised而不是supertest,因为当你需要运行大量请求时,这可以使事情变得更容易.这个库,加上蓝鸟可以让你的测试变得更简单.
这个要点是我重写你的测试,使用Bluebird
承诺supertest-as-promised
,并对我改变的内容发表评论.