你如何POST到Capybara的URL?

Cli*_*ton 34 ruby-on-rails webrat cucumber capybara

刚刚从Cucumber + Webrat切换到Cucumber + Capybara,我想知道如何将内容发布到Capybara的URL.

在Cucumber + Webrat中我能够迈出一步:

When /^I send "([^\"]*)" to "([^\"]*)"$/ do |file, project|
  proj = Project.find(:first, :conditions => "name='#{project}'")
  f = File.new(File.join(::Rails.root.to_s, file))
  visit "project/" + proj.id.to_s + "/upload",
        :post, {:upload_path => File.join(::Rails.root.to_s, file)}
end
Run Code Online (Sandbox Code Playgroud)

但是,Capybara文档提到:

visit方法只接受一个参数,请求方法总是GET.always GET.

如何修改我的步骤以便Cucumber + Capybara对URL进行POST?

Cli*_*ton 22

最近我发现这篇精彩的博文.对于像托尼这样的案例以及你真正希望在你的游戏中发布内容的内容来说,这是很棒的:

对于我的情况,这成了:

def send_log(file, project)
  proj = Project.find(:first, :conditions => "name='#{project}'")
  f = File.new(File.join(::Rails.root.to_s, file))
  page.driver.post("projects/" + proj.id.to_s + "/log?upload_path=" + f.to_path)
  page.driver.status_code.should eql 200
end
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,我为'<Capybara :: Selenium :: Driver:0x3f75e10>(NoMethodError)`获得了'未定义的方法'帖子'. (19认同)
  • 看起来最新版本的capybara打破了这个 - 我的宝石文件目前限制为早期版本:gem'capybara',"0.4.1.2" (3认同)

Mik*_*ike 22

你可以这样做:

rack_test_session_wrapper = Capybara.current_session.driver
rack_test_session_wrapper.submit :post, your_path, nil
Run Code Online (Sandbox Code Playgroud)
  • 您可以替换:post您关心的任何方法,例如:put:delete.
  • 替换your_path为您想要的Rails路径,例如rack_test_session_wrapper.submit :delete, document_path(Document.last), nil将删除我的应用程序中的最后一个文档.

  • 我为'<Capybara :: Poltergeist :: Driver:0x007f8cdcc699c0>` - Capybara 2.9.0获取`undefined方法`submit' (3认同)

Hen*_*k N 10

如果您的驱动程序没有post(例如,Poltergeist没有),您可以这样做:

session = ActionDispatch::Integration::Session.new(Rails.application)
response = session.post("/mypath", my_params: "go_here")
Run Code Online (Sandbox Code Playgroud)

但请注意,此请求发生在新会话中,因此您必须通过该response对象对其进行断言.

正如其他地方所述,在Capybara测试中,您通常希望通过提交表单来进行POST,就像用户一样.我使用上面的代码来测试如果POST在另一个会话中发生(通过WebSockets)会发生什么,因此表单不会删除它.

文档:

  • post返回的response对象只是状态码,之后可以通过`session.response`访问response对象,它也有#body方法。与这条信息一起,在 Capybara 之外进行 POSTing 效果非常好! (2认同)

Ari*_*jan 9

Capybara visit只做GET请求.这是设计的.

要让用户执行a POST,他必须单击按钮或提交表单.使用浏览器没有其他方法可以做到这一点.

测试此行为的正确方法是:

visit "project/:id/edit" # This will only GET
attach_file "photo", File.open('cute_photo.jpg')
click_button 'Upload' # This will POST
Run Code Online (Sandbox Code Playgroud)

如果你想测试API,我建议使用spec/request而不是黄瓜,但那只是我.

  • 测试POST可能很有用.例如,如果可以使用它来测试你的代码是否能够抵御那些试图发布不允许的东西的机器人. (4认同)

sim*_*nks 5

我知道答案已被接受,但我想提供一个更新的答案.以下是来自Anthony EdenCorey Haines的技术,它将Rack :: Test传递给Cucumber的World对象:

使用Cucumber和Rack :: Test测试REST API

通过这种技术,我能够在步骤定义中直接发送帖子请求.在编写步骤定义时,从它自己的规范中学习Rack :: Test API非常有帮助.

# feature
  Scenario: create resource from one time request
    Given I am an admin
    When I make an authenticated request for a new resource
    Then I am redirected  
    And I see the message "Resource successfully created" 

# step definitions using Rack::Test
When /^I make an authenticated request for a new resource$/ do
  post resources_path, :auth_token => @admin.authentication_token
  follow_redirect!
end

Then /^I am redirected$/ do
  last_response.should_not be_redirect
  last_request.env["HTTP_REFERER"].should include(resources_path)
end

Then /^I see the message "([^"]*)"$/ do |msg|
  last_response.body.should include(msg)
end
Run Code Online (Sandbox Code Playgroud)

  • 尽管您的示例不是必需的,但最好使用page.driver.post,因为它与其他步骤处于相同的上下文中。 (2认同)