Feech
Feech

Reputation: 4102

Understanding Mocha syntax in an 'integration' test

I have a pretty extensive background with Ruby and Rspec. However, as I'm learning Node and Mocha, I've come across syntax that I can't seem to understand.

Using this tutorial as an example, testing routes consists of the following (using CoffeeScript). It should also be noted that I've seen the following example many other places that explain Mocha to beginners.

require "should"
routes = require "../routes/index"

describe "routes", ->

  describe "index", ->

    it "should display index with posts", ->
      req = null
      res =
        render: (view, vars) ->
          view.should.equal 'index'
          vars.title.should.equal('My Coffeepress Blog')
      routes.index(req, res)

If I understand correctly, this test sets up mock request and response variables (req and res, respectively) and sends them to the routes.index() function.

What I don't understand, though, is why and how it's making assertions in the render() function call. This seems to be a totally different approach to testing, as I'm used to setting up the data, testing that data against an expected value, and tearing the data down. Here, it seems as though part of "setting up the data" (creating a mock res object) is making the assertions.

Can anyone explain this to someone fluent with Rspec?

Upvotes: 3

Views: 946

Answers (1)

SonOfNun
SonOfNun

Reputation: 957

The render function is being invoked, I presume, inside your index route. It probably looks something like:

index: (req, res, next) ->
    res.render 'index', { title: 'My Coffeepress Blog'}

You are passing in a stub response exposing the render method so you can intercept the call and assert the invocations; namely the first argument (the view parameter) and the data (the vars object). This is all that is required since going beyond that would of course be testing the underlying framework.

Making assertions on callbacks often results in kind of 'upside down' looking tests because code doesn't read top=>down. This is life in the async/callback world though.

If it is annoying you can capture the invocation in a local variable and make assertions after the fact, but this starts to be unnecessarily verbose once you've been coding callbacks for a while:

# snip
viewName = null
locals = null
res: 
    render: (view, vars) > 
        viewName = view
        locals = vars
routes.index (req, res)
viewName.should.equal 'index'
locals.title.should.equal 'My Coffeepress Blog'

Does that help?

Upvotes: 2

Related Questions