Reputation: 4102
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
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