3

我在 Ruby 和 Rspec 方面有相当广泛的背景。然而,当我学习 Node 和 Mocha 时,我遇到了我似乎无法理解的语法。

本教程为例,测试路由包括以下内容(使用 CoffeeScript)。还应该注意的是,我在许多其他地方看到过以下示例,这些示例向初学者解释了 Mocha。

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)

如果我理解正确,此测试会设置模拟请求和响应变量(分别为 req 和 res)并将它们发送到 routes.index() 函数。

不过,我不明白的是,它为什么以及如何在 render() 函数调用中进行断言。这似乎是一种完全不同的测试方法,因为我习惯于设置数据,根据预期值测试数据,然后将数据分解。在这里,似乎“设置数据”(创建模拟 res 对象)的一部分正在做出断言。

任何人都可以向精通 Rspec 的人解释这一点吗?

4

1 回答 1

2

我想,该render函数正在您的index路线内被调用。它可能看起来像:

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

您正在传递一个暴露render方法的存根响应,以便您可以拦截调用并断言调用;即第一个参数(view参数)和数据(vars对象)。这就是所有需要的,因为超出此范围当然会测试底层框架。

对回调进行断言通常会导致看起来“颠倒”的测试,因为代码不会读取 top=>down。这是异步/回调世界中的生活。

如果这很烦人,您可以在局部变量中捕获调用并在事后进行断言,但是一旦您编写了一段时间的回调代码,这就会开始变得不必要地冗长:

# 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'

这有帮助吗?

于 2012-08-27T04:07:53.593 回答