javascript - 使用 jasmine 测试对象中的事件处理程序

标签 javascript event-handling coffeescript jasmine

我在我的 CoffeeScript ala Spinejs 中使用了一个简单的 MVC 模式.它允许我在实例化之前通过指定一个事件对象来添加事件监听器:

class Controller extends Module
    @include Events

    eventSplitter: /^(\S+)\s*(.*)$/
    events: {}

    constructor: (view = '<div/>') ->
        @view = $(view)
        @delegate key, func for key, func of @events

    delegate: (key, func) ->
        match = key.match @eventSplitter
        if match[2] is ''
            @view.on( match[1], $.proxy(@[func], @) )
        else
            @view.on( match[1], match[2], $.proxy(@[func], @) )

快速解释 - 您传入一个选择器、元素或 html 字符串,它们被分配给 View 属性。然后委托(delegate)方法获取一个事件对象并循环并将事件监听器分配给 View 节点本身,或者将事件处理程序从子元素委托(delegate)给 View 节点:

class Con extends Controller
    events:
        'click' : 'parent'
        'mouseover span' : 'child'

    parent: (e) ->
        console.log('div was clicked')

    child: (e) ->
        console.log('span was moused over')

con = new Con('<div><span>test</span></div>')

con.view.trigger('click') // --> 'div was clicked'
con.view.find('span') // --> 'span was moused over'

我正在努力用 Jasmine 对此进行测试。以下测试将通过:

expect( con.view ).toHandle('mouseover')
expect( con.view ).toHandle('click')

这至少允许我测试是否设置了某种处理程序,但我想测试设置的实际处理程序。我试图监视事件处理程序,但它们似乎从未被调用过。

spyOn(con, 'parent')
con.view.trigger('click')

expect( con.parent ).toHaveBeenCalled() // fails!

我还试图窥探原型(prototype)中的实际方法。

spyOn( Con.prototype, 'parent' )
con.view.trigger('click')

expect( Con.prototype.parent ).toHaveBeenCalled() // fails!

如果我显式调用该方法,我可以让测试通过:

con.parent();
expect( con.parent ).toHaveBeenCalled() // passes!

我认为 spy 在被事件执行时会失败,因为事件处理程序是如何通过 jQuery 'on' 方法引用的。因为它是一个函数,但它不是 con 对象上的实际方法。

如有任何帮助,我们将不胜感激。也欢迎任何一般测试建议。

最佳答案

解决方案似乎是在对象外部定义 spy 。我刚刚发现了创建裸 spy 的 jasmine.createSpy() 方法,这正是我所需要的:

describe "Controller", ->
    clickSpy = jasmine.createSpy()
    mouseSpy = jasmine.createSpy()

    class Con extends CRDGN.Controller
        events:
            'click' : 'parent'
            'mouseover span' : 'child'

        parent: clickSpy

        child: mouseSpy

    con = new Con('<div><span>test</span></div>')

it "should attach listeners through an events object", ->
    con.view.trigger('click')
    expect( clickSpy ).toHaveBeenCalled()

    con.view.find('span').trigger('mouseover')
    expect( mouseSpy ).toHaveBeenCalled()

关于javascript - 使用 jasmine 测试对象中的事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11904486/

相关文章:

javascript - 对 URL 的异步调用

javascript - 使用 Javascript/jQuery 向下翻页?

javascript - jQuery.trigger ('click' ) 在 IE8 中产生 "change"事件

c# - 我应该使用 EventHandler<T> 和/或 EventArgs 委托(delegate)模式吗?

javascript - 在 javascript 环境中执行

javascript - jquery超时解决方案?

javascript - 绝对路径 Css/Js

c# - 如果快速单击多次,则 ChildWindow 关闭按钮事件处理程序会执行多次

ruby-on-rails - 配置 Ruby on Rails 以生成 .js 而不是 js.coffee

node.js - Node.js如何编译coffeescript?