如何断言 url 是从 javascript 使用 rspec 和水豚调用的

How to assert url was called from javascript using rspec and capybara

场景:

我们使用水豚集成测试来测试我们的前端管道 (javascript) 是否连接正确。

有时我们需要验证测试的是:

  1. 已在页面上正确呈现内容
  2. js调用正确了吗url打开交互

问题:

上面的第 1 项很简单。但是,对于第 2 项,我似乎找不到简单的说法:

Assert that url was called from js in browser.

示例:

it "should call coorect url with correct query string" do
  visit widgets_path

  # THIS IS WHAT I NEED TO KNOW
  expect(something).to receive(:some_method).with(url: "my/test/url", params: {per_page: 2})

  # In other words, I don't want the controller action to run. I don't care about the result since the controller is being tested elsewhere.
  # I just need to know that the correct URL was called with the correct params.

  within 'ul.pagination' do
    click_on '2'
  end
end

我试过模拟控制器动作,但无法检查参数。或者有吗?如果不检查参数,我怎么知道是否发送了正确的内容?我只知道这是正确的路线,这还不够。

如果我可以检查参数,那么这将得到解决...但否则呢?

Capybara 集成测试有意不支持这一点。它们是端到端的黑盒测试,通常不应被嘲笑,实际上只支持检查浏览器中用户可见的内容。在您的示例中,这意味着期望 JS 调用特定 URL 引起的任何可见变化。像

expect(page).to have_css('div.widget', count: 2) 

如果您正在寻找 Rails 解决方案,就在这里!使用 Rails 5.1.3.

测试

1) 创建请求参数匹配器spec/support/matchers/request_with_params.rb

RSpec::Matchers.define :request_with_params do |params| match { |request| request.params.symbolize_keys.slice(*params.keys) == params } end

2) 为您的验收测试创建一个辅助方法(如果需要,您可以使用一些逻辑来传递符号而不是 class UsersController -> :users)

def expect_request(controller, action, params = {}) expect_any_instance_of(ActionDispatch::Routing::RouteSet::Dispatcher) .to receive(:dispatch) .with(controller, action.to_s, request_with_params(params), anything) end end

3) 使用它!

expect_request(UsersController, :index)

或带参数

expect_request(UsersController, :show, { id: 1 })

4) 还有另一种方法可以使用 https://github.com/oesmith/puffing-billy 检查此 gem 以拦截浏览器发送的请求。但是,如果您只需要模拟对后端应用程序的某些请求,则可能有点矫枉过正。