[AWDwR4] No JQuery call matches [:html, "#cart"]
实践11.5 Testing Ajax Changes,按照书上的写了test_should_create_line_item_via_ajax的测试,rake test:functionals时有错:
1) Failure: test_should_create_line_item_via_ajax(LineItemsControllerTest) [/home/csd/railsProjects/depot/test/functional/line_items_controller_test.rb:42]: Expected at least 1 element matching "tr#current_item", found 0.
我首先想到可能是line_item是空或者是cart为空,导致不会render cart 或者line_item。可是我不知道怎么在test里把服务器的响应打印出来。我还不会调试Rails呢,于是就去看了好长时间的Rails debug 。
我在app/controllers/line_items_controller.rb中各种加日志来打印出cart和line_items变量的值,发现都是对的。后来偶然机会发现可以打印出服务器的response。我在test "should create line_item via ajax"这个测试用例中使用这句:
puts "ajax reponse: #{@response.body}"
发现服务器返回的response没啥错误,返回的jquery语句是对的。后来上http://intertwingly.net/projects/AWDwR4/checkdepot-32/section-11.6.html 瞅了一眼,发现测试的断言语句有变化:
assert_select_jquery :html, '#cart' do
assert_select 'tr#current_item td', /Programming Ruby 1.9/
end
查了一下 assert_select_jquery 【http://rubydoc.info/gems/jquery-rails/2.1.3/ActionDispatch/Assertions/SelectorAssertions#assert_select_jquery-instance_method】
assert_select_jquery【https://github.com/rails/jquery-rails/blob/master/lib/jquery/assert_select.rb】 是jquery_rails中提供的,从一个JQuery响应中选择内容。
解释可以见这里。assert_select_jquery(*args, &block) ,后来理解了method即函数的意思,而不是put, delete, get等HTTP method。咱们这里是选出 id为cart的元素并且其上的jquery调用为html的内容,然后去检查这段内容里是否包含 'tr#current_item td',并且其值是 Programming Ruby 1.9
可是rake test:functionals 后还是有错:
1) Failure: test_should_create_line_item_via_ajax(LineItemsControllerTest) [/home/csd/railsProjects/depot/test/functional/line_items_controller_test.rb:42]: No JQuery call matches [:html, "#cart"]
我在网上搜了好长时间,都没有找到相关的太多信息,我就想肯定是我用错了,再次确定了一下,作者的网站上也是这么写的,assert_select_jquery 的调用应该没错,实在没招了就看了看它的源码,隐约感觉是匹配的有问题,所以测试时提示找不到。花了一个小时温习正则表达式,并分析源码中的匹配过程,发现原来是assert_select_jquery 匹配 method时,要求method后面参数中,HTML必须是双引号包裹的,不能是单引号。于是找到app/views/line_items/create.js.erb修改
$('#cart').html('<%= escape_javascript(render(@cart)) %>');
为
$('#cart').html("<%= escape_javascript(render(@cart)) %>");
再次跑测试,果然通过了。
经测试发现
assert_select 'tr#current_item td', /Programming Ruby 1.9/
和
assert_select 'tr#current_item', /Programming Ruby 1.9/
都是可以的。不明白为啥呢,如果有明白的人请指点一下。
发现没有Rails debug的中文,我看了一遍,感觉不是很难,想这个月抽空翻译一下,为开源做点微薄的贡献吧。
回到本系列的目录