Capybara JavaScript 测试的 XHR 请求存根
Posted
技术标签:
【中文标题】Capybara JavaScript 测试的 XHR 请求存根【英文标题】:XHR request stubbing for Capybara JavaScript Testing 【发布时间】:2011-10-24 20:43:41 【问题描述】:我正在尝试编写一个request_spec
,它使用一个执行 ajax 自动完成查找并返回有效结果然后激活提交按钮的表单来测试页面的功能。
我想知道是否有人遇到过同样的问题并找到了某种方法或参考资料来通过此测试。
宝石文件
gem 'rake', '0.8.7'
gem 'rails', '2.3.5'
group :test do
gem "capybara", :git => "git://github.com/jnicklas/capybara.git"
gem 'rspec', '1.3.1'
gem 'rspec-core'
gem 'rspec-rails', '1.3.2'
gem 'webmock', '1.4.0'
end
html
...
<fieldset>
<label>Enter a Destination</label>
<%= text_field_tag :reviewable_name, nil, :id => "destination_autocomplete", :class => 'textfield' %>
<ul>
<li>
<h3 class="disabled">
<%= submit_tag "Read reviews", :id => "read_a_destination_review", :name => "agree", :class => "read_review", :disabled => false %>
</h3>
</li>
<li class="or">or</li>
<li>
<h3>
<%= submit_tag "Write review", :id => "write_a_destination_review", :name => "agree", :class => "write_review", :disabled => false %>
</h3>
</li>
</ul>
</fieldset>
...
javascript (jQuery 1.4.4)
...
$("#hotel_autocomplete, #destination_autocomplete").autocomplete(
source: function(request, response)
$.getJSON('/ajax/search_reviewable?type=destination&q=' + request.term,
function(results, status)
if(status == 'success')
//make it regex safe
var term = request.term.replace(/([\^\$\(\)\[\]\\\*\.\+\?\|\\])/gi, "\\$1");
term = term.split(' ').join('|');
for(var i = 0; i < results.length; i++)
results[i].value = results[i].label;
results[i].label = results[i].value.replace(new RegExp("("+term+")", "gi"),'<strong>$1</strong>');
response(results);
);
,
minLength: 3,
delay: 500,
select: function( event, ui ) ...
);
...
JSON 响应
/ajax/search_reviewable?type=destination&q=florida
["label":"Florida","id":124]
RSpec 测试
it "should activate submit button", :js => true do
stub_request(:get, "/ajax/search_reviewable/type=destination&q=florida").to_return(:body => %Q["label":"Florida","id":124], :headers => "Content-Type" => "applicaation/json; charset=utf-8", "Accept" => "*/*")
fill_in("destination_autocomplete", :with => "florida")
page.execute_script(%Q$("#destination_autocomplete").trigger("keyup");)
find(".ui-menu-item a").click
# should post to '/review/new', :id => 124
page.should have_content("Write a Destination Review")
end
测试失败,因为该规范无法在 JavaScript 中存根 XHR 请求。
感谢您对 cmets 的回复和帮助。
【问题讨论】:
【参考方案1】:我设法找到了解决此问题的方法。
实际发生了什么,AJAX 请求页面/ajax/search_reviewable?type=destination&q=$1
正在向另一个服务发出 Net::HTTP 请求。
这个请求需要用我需要的响应来存根。
stub_request(:get, ".../all_by_partial_name/Florida/").to_return(
:body => %Q["label":"Florida","id":124],
:headers => "Content-Type" => "applicaation/json; charset=utf-8", "Accept" => "*/*"
)
经过一番大研究,我发现你必须在 JavaScript 中触发一个事件才能通过测试。
来源。 Clicking AutoComplete Options Gist
现在规范示例如下所示
before(:each) do
stub_request(:get, ".../all_by_partial_name/Florida/").to_return(
:body => %Q["label":"Florida","id":124],
:headers => "Content-Type" => "applicaation/json; charset=utf-8", "Accept" => "*/*"
)
end
it "should activate submit button and direct to new review", :js => true do
fill_in("destination_autocomplete", :with => "florida")
sleep 2
page.execute_script(%Q$(".ui-menu-item a:eq(0)").trigger("mouseenter").click();)
find_button("write_a_destination_review").click
page.should have_content("Write a Destination Review")
end
我希望这可以帮助您解决 RSpec JQuery 问题。
【讨论】:
对于最终从 Google 来到这里的人,值得注意的是,这需要webmock
gem,它不允许所有真正的 HTTP 请求,所以如果你的套件依赖于真正的请求,这个解决方案可能会失败不适合你。以上是关于Capybara JavaScript 测试的 XHR 请求存根的主要内容,如果未能解决你的问题,请参考以下文章
如何使用rails cucumber,rspec,capybara在视图(dhtml)中测试动态部分?
capybara webkit 无法加载 mailto url