node.js - Supertest double callback while iterating over array -
as learning exercise, i'm trying version of bowling game kata running using node , express, , i'm seeing peculiar issue. use understanding why knows node , express better do.
after writing strike test case while trying strike test case working, when try run below tests using mocha @ command line, following supertest error: "uncaught typeerror: undefined not function" @ /users/cdurfee/bitbucket/neontapir/node_modules/supertest/lib/test.js:125:21
.
however, if comment out seemingly innocuous line in game.js (total += rolls[ball + 2];
), there no failures, of course behavior wrong. suspect it's array out of bounds issue, don't know way figure out.
here's full contents of both files , console output of mocha.
08:55 $ mocha --reporter spec scoring bowling game gutter game ✓ should return 0 single pin game ✓ should return 20 spare ✓ should return 16 after spare , 3 strike ✓ should return 24 after strike, 4 , 3 1) should return 24 after strike, 4 , 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 bowling game strike should return 24 after strike, 4 , 3: uncaught typeerror: undefined not function @ /users/cdurfee/bitbucket/neontapir/node_modules/supertest/lib/test.js:125:21 @ test.request.callback (/users/cdurfee/bitbucket/neontapir/node_modules/supertest/node_modules/superagent/lib/node/index.js:660:30) @ clientrequest.<anonymous> (/users/cdurfee/bitbucket/neontapir/node_modules/supertest/node_modules/superagent/lib/node/index.js:628:10) @ clientrequest.eventemitter.emit (events.js:95:17) @ socket.socketerrorlistener (http.js:1547:9) @ socket.eventemitter.emit (events.js:95:17) @ net.js:441:14 @ process._tickcallback (node.js:415:13)
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; (var frame = 0; frame < 10; frame++) { if (rolls[ball] + rolls[ball + 1] == 10) { total += rolls[ball + 2]; // line causes double callback } total += rolls[ball] + rolls[ball + 1]; ball += 2; } res.send(200, {score: total}); }); app.listen(process.env.port || 3000);
test/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) { (var = 0; < times; i++) { roll(pins); } }; describe('scoring 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 , 3', function() { roll(6); roll(4); // spare roll(3); rollmany(17,0); assertscoreequals(16); }); }); // not expected pass @ moment describe('strike', function() { it('should return 24 after strike, 4 , 3', function() { roll(10); // strike roll(4); roll(3); rollmany(17,0); assertscoreequals(24); }); }); // not expected pass @ moment describe('perfect game', function() { it('should return 300', function() { rollmany(12,10); assertscoreequals(300); }); }); });
adding previous comment
i see test cases not asynchronous, problem.
you should have callback: done
describe('gutter game', function() { it('should return 0', function(done) { // callback provided argument mocha rollmany(20,0); assertscoreequals(0); done(); // needs called when test finished, async operations. }); });
i suggest perhaps using supertest-as-promised instead of supertest, can make things easier when need run lot of requests. library, plus perhaps bluebird can make tests yours simpler.
this gist has rewrite of tests, using bluebird
promises , supertest-as-promised
, comments on i've changed.
Comments
Post a Comment