Javascript 轨道&x2B;jasmineajax:测试由Ajax:success触发的代码的正确方法是什么(jqueryujs)
我试图测试一个内部库,它在Javascript 轨道&x2B;jasmineajax:测试由Ajax:success触发的代码的正确方法是什么(jqueryujs),javascript,jquery,ruby-on-rails,ajax,jasmine,Javascript,Jquery,Ruby On Rails,Ajax,Jasmine,我试图测试一个内部库,它在ajax:success事件中触发了一些JS行为 库创建的链接如下所示: <%= link_to 'click here', '/some_path', class: 'special-link', remote: true %> $document.on('myCustomEvent', '.some_selector', somecode.custom_func); $document.on('ajax:error', '.some_selector'
ajax:success
事件中触发了一些JS行为
库创建的链接如下所示:
<%= link_to 'click here', '/some_path', class: 'special-link', remote: true %>
$document.on('myCustomEvent', '.some_selector', somecode.custom_func);
$document.on('ajax:error', '.some_selector', somecode.failure_func);
该库在浏览器中按预期工作。但是,当我试图在Jasmine中通过调用$('.special link').click()
来测试库时,无法观察到对DOM的理想效果
问题似乎是,ajax:success
事件没有被触发:
describe 'my library', ->
beforeEach ->
MagicLamp.load('fixture') # Fixture library that injects the link above to the DOM
jasmine.Ajax.install()
jasmine.Ajax.stubRequest('/some_path').andReturn({
responseText: 'response that is supposed to trigger some effect on the DOM'})
afterEach ->
jasmine.Ajax.uninstall()
# Works. The fixtures are loading properly
it '[sanity] loads fixtures correctly', ->
expect($('.special-link').length).toEqual(1)
# Works. The jquery-ujs correctly triggers an ajax request on click
it '[sanity] triggers the ajax call', ->
$('.special-link').click()
expect(jasmine.Ajax.requests.mostRecent().url).toContain('/some_path')
# Works. Code that tests a click event-triggering seems to be supported by Jasmine
it '[sanity] knows how to handle click events', ->
spy = jasmine.createSpy('my spy')
$('.special-link').on 'click', spy
$('.special-link').click()
expect(spy).toHaveBeenCalled()
# Does not work. Same code from above on the desired `ajax:success` event does not work
it 'knows how to handle ajax:success events', ->
spy = jasmine.createSpy('my spy')
$('.special-link').on 'ajax:success', spy
$('.special-link').click()
expect(spy).toHaveBeenCalled()
测试在
ajax:success
事件中运行的代码对DOM的影响的正确方法是什么?您是否尝试过简单地监视ajax
函数?为此,需要使用spyOn
并强制它调用success
事件处理程序。这将让您测试在调用时预期会发生什么
it 'knows how to handle ajax:success events', ->
spyOn($, "ajax").and.callFake( (e) ->
e.success({});
)
$('.special-link').click()
# expect some method to be called or something to be changed in the DOM
下面是我们如何在我的团队中处理这类事情
it 'knows how to handle ajax:success events', ->
spyOn($.fn, 'on');
$('.special-link').click()
expect($.fn.on).toHaveBeenCalledWith('ajax:success',
'.special-link'
some_func);
此模式也可以很好地扩展到测试其他“on”事件。假设我们有一些jQuery,如下所示:
<%= link_to 'click here', '/some_path', class: 'special-link', remote: true %>
$document.on('myCustomEvent', '.some_selector', somecode.custom_func);
$document.on('ajax:error', '.some_selector', somecode.failure_func);
然后我们可以使用以下模式对其进行测试:
beforeEach ->
spyOn($.fn, 'on');
somecode.init();
测试Ajax故障
it('indicates failure after ajax error', ->
expect($.fn.on).toHaveBeenCalledWith('ajax:error',
'.some_selector',
somecode.failure_func);
测试Ajax是从自定义事件调用的
it('indicates ajax call from custom event', ->
expect($.fn.on).toHaveBeenCalledWith('myCustomEvent',
'.some_selector',
somecode.custom_func);
经过大量调试,我找到了一个解决方案 当我发布我的问题时,我犯了3个严重错误 错误#1:
jasmine.Ajax.stubRequest
路径不是相对的
Ajax调用没有正确地存根,因为路径不应该是相对的/some\u路径
,而应该是绝对的http://localhost:3000/some_path
从浏览器进行测试时
换句话说,不是:
jasmine.Ajax.stubRequest('/some_path')
jasmine.Ajax.stubRequest(/.*\/some_path/).andReturn({
responseText: 'response that is supposed to trigger some effect on the DOM'})
我应该使用regexp版本:
jasmine.Ajax.stubRequest(/.*\/some_path/)
错误2:jasmine.Ajax.andReturn
必须包含coentType
而不是:
jasmine.Ajax.stubRequest('/some_path')
jasmine.Ajax.stubRequest(/.*\/some_path/).andReturn({
responseText: 'response that is supposed to trigger some effect on the DOM'})
我应该这样做:
jasmine.Ajax.stubRequest(/.*\/some_path/).andReturn({
contentType: 'text/html;charset=UTF-8',
responseText: 'response that is supposed to trigger some effect on the DOM'})
如果没有它,将触发ajax:error
,而不是ajax:success
,并触发parseerror
错误3:ajax:success
处理程序被异步调用
这些代码行:
spy = jasmine.createSpy('my spy')
$('.special-link').on 'ajax:success', spy
$('.special-link').click()
expect(spy).toHaveBeenCalled()
不要工作,因为调用spy()
的ajax:success
处理程序在到达expect(spy).toHaveBeenCalled()
后被异步调用。您可以在中阅读更多关于此的信息
把它们放在一起
这是有效的代码,只关注最后的it
语句,这是原始问题背后的主要意图:
describe 'my library', ->
beforeEach ->
MagicLamp.load('fixture') # Fixture library that injects the link above to the DOM
jasmine.Ajax.install()
jasmine.Ajax.stubRequest(/.*\/some_path/).andReturn({
contentType: 'text/html;charset=UTF-8',
responseText: 'response that is supposed to trigger some effect on the DOM'})
afterEach ->
jasmine.Ajax.uninstall()
# Restructuring the original `it` statement to allow async handling
describe 'ajax:success event handling', ->
spy = jasmine.createSpy('spy')
# Ensures no `it` statement runs before `done()` is called
beforeEach (done) ->
$('.special-link').on 'ajax:success', ->
spy()
done()
$('.special-link').click()
it 'knows how to handle ajax:success events', ->
expect(spy).toHaveBeenCalled()
希望这对其他人有帮助。我最近回答了类似的问题,这有什么帮助吗?