Help needed : impossible to test the simplest http request

4,336 views
Skip to first unread message

DjebbZ

unread,
Aug 18, 2012, 11:07:36 AM8/18/12
to moc...@googlegroups.com
Hi guys

I'm throwing a SOS here. I'm new to nodejs development and to writing tests. I'm trying to write a simple Express app with a small REST-like API to CRUD books, movies etc. The basic boilerplate code works fine, but when I try to execute my (first and basic) test, it throws me an error I can't understand...

Using node 0.8.0 with nvm, express 3, mocha latest 1.3.x on OS X 10.6.8

Here the basic router code :

app.get('/media', function(req, res) {
  res.json({});
});

Here's the test using Mocha, request and Chai :

describe('HTTP REST API', function() {
  describe('GET "/media"', function() {
    it('should return OK (code 200)', function(done) {
      // the url is http://localhost:3000/media
      request.get(path.join(baseUrl, 'media'), function(err, res, body) {
        expect(res.statusCode).to.equal(200);
        done();
      });
    });
  });
});

The output is strange, it tells me that 'res' is undefined...

  ․

  ✖ 1 of 1 test failed:

  1) HTTP REST API GET "/media" should return OK (code 200):
     TypeError: Cannot read property 'statusCode' of undefined
      at Request._callback (/Users/khalid_jebbari/Sites/mediatheque/test/app.test.js:25:19)
      at Request.init.self.callback (/Users/khalid_jebbari/Sites/mediatheque/node_modules/request/main.js:120:22)
      at Request.EventEmitter.emit (events.js:88:17)
      at Request.init (/Users/khalid_jebbari/Sites/mediatheque/node_modules/request/main.js:167:10)
      at new Request (/Users/khalid_jebbari/Sites/mediatheque/node_modules/request/main.js:103:8)
      at Function.request [as get] (/Users/khalid_jebbari/Sites/mediatheque/node_modules/request/main.js:939:11)
      at Context.<anonymous> (/Users/khalid_jebbari/Sites/mediatheque/test/app.test.js:24:15)
      at Test.Runnable.run (/Users/khalid_jebbari/.nvm/v0.8.0/lib/node_modules/mocha/lib/runnable.js:171:15)
      at Runner.runTest (/Users/khalid_jebbari/.nvm/v0.8.0/lib/node_modules/mocha/lib/runner.js:300:10)
      at Runner.runTests.next (/Users/khalid_jebbari/.nvm/v0.8.0/lib/node_modules/mocha/lib/runner.js:346:12)
      at next (/Users/khalid_jebbari/.nvm/v0.8.0/lib/node_modules/mocha/lib/runner.js:228:14)
      at Runner.hooks (/Users/khalid_jebbari/.nvm/v0.8.0/lib/node_modules/mocha/lib/runner.js:237:7)
      at next (/Users/khalid_jebbari/.nvm/v0.8.0/lib/node_modules/mocha/lib/runner.js:185:23)
      at Runner.hook (/Users/khalid_jebbari/.nvm/v0.8.0/lib/node_modules/mocha/lib/runner.js:205:5)
      at process.startup.processNextTick.process._tickCallback (node.js:244:9)

I don't get it. The response should be a normal response object. I verified it by
1. visiting the url in Chrome and checking the network tab : I do have a 200 answer of type application/json
2. open a node REPL and typing :
var r = require('request'); r ('http://localhost:3000/media', function(e,r,b) { console.log(r.statusCode); });
I does print '200'

I have no idea why from my test code the app is unreachable whereas it's running in another Terminal tab... I even switched from Chai to Expect.js, same problem.  And even rewrote the tests using API-easy. Here's the output from API-easy (it may help...) :

GET "/media" A GET to /http:/localhost:3000/media 
      ✗ should respond with 200 
        » expected null, got { 
      message: 'getaddrinfo ENOENT', 
      stack: 'Error: getaddrinfo ENOENT\n    at errnoException (dns.js:31:11)\n    at Object.onanswer [as oncomplete] (dns.js:123:16)', 
      code: 'ENOTFOUND', 
      arguments: undefined, 
      type: undefined, 
      errno: 'ENOTFOUND', 
      syscall: 'getaddrinfo' 
  } // dns.js:31 

I understand that it may not be related to Mocha but to my machine, but I have no idea why, especially since the app runs just fine, but only the test fails...

Thanks in advance !

Kazuhito Hokamura

unread,
Aug 18, 2012, 12:03:29 PM8/18/12
to moc...@googlegroups.com
Probably it is a problem of path.join.

path.join('http://localhost:3000', 'media'); //=>
'http:/localhost:3000/media'

`http:/...` is invalid url.

Try this.

request.get('http://localhost:3000/media', function(err, res, body) {
expect(res.statusCode).to.equal(200);
done();
});


2012/8/19 DjebbZ <khalid....@gmail.com>:
--
----------------------------------------
Name: Kazuhito Hokamura
Twitter: @hokaccha
Email: k.hok...@gmail.com
----------------------------------------

DjebbZ

unread,
Aug 18, 2012, 12:12:51 PM8/18/12
to moc...@googlegroups.com
How can I say... I'm stupid. One should use the url module to manipulate urls, not the path module. Lesson learned.

Everything worked fine when I wrote :

request(url.resolve(baseUrl, 'media'), ...

Dômo arigato Hokamura-san.

vision media [ Tj Holowaychuk ]

unread,
Aug 18, 2012, 12:35:13 PM8/18/12
to moc...@googlegroups.com
you may want to check out https://github.com/visionmedia/supertest
request is not the greatest for tests

Domenic Denicola

unread,
Aug 18, 2012, 12:40:15 PM8/18/12
to <mochajs@googlegroups.com>, moc...@googlegroups.com
Also you should always do if (err) return done(err). res was undefined because you were only getting an err passed to you. If you had that line the output would be much less confusing.

DjebbZ

unread,
Aug 18, 2012, 1:26:14 PM8/18/12
to moc...@googlegroups.com
Does that mean I should start with if (err) return done(err) and end with done() ?

Domenic Denicola

unread,
Aug 18, 2012, 1:53:30 PM8/18/12
to <mochajs@googlegroups.com>, moc...@googlegroups.com
Yeah exactly. done with no arguments = success, with an error argument = failure.

DjebbZ

unread,
Aug 18, 2012, 2:11:55 PM8/18/12
to moc...@googlegroups.com
Thank you guys. I may try supertest as well, since it helps writing less code (something I like).
Reply all
Reply to author
Forward
0 new messages