使用RSpec的'all`匹配器与Capybara的'have_css`匹配器时出错

时间:2014-09-17 23:44:38

标签: ruby-on-rails rspec capybara rspec-rails

我刚刚使用RSpec(和Capybara)开始使用功能规格。我正在测试我的ActiveAdmin仪表板,我想检查所有面板是否都有一个订单表,如下所示:

feature 'admin dashboard', type: :feature do
  def panels
    page.all('.column .panel')
  end

  describe 'all panels' do
    it 'have an orders table' do
      expect(panels).to all(have_css('table.orders tbody'))
    end
  end
end

我在单元测试中经常使用all匹配器,但在包装Capybara的have_css匹配器时它似乎不起作用,因为我'我收到以下错误:

Failure/Error: expect(panels).to all(have_css('table.orders tbody'))
TypeError:
  no implicit conversion of Capybara::RackTest::CSSHandlers into String

我是否认为RSpec的内置all匹配器也可以与其他匹配器一起使用?

注意:我在这个例子中使用describeit代替featurescenario,因为我测试的是输出而不是用户互动场景(参见我的other question)。

2 个答案:

答案 0 :(得分:12)

不幸的是,RSpec的all和Capybara all之间存在冲突,请参见Capybara Issue 1396。您呼叫的all实际上是Capybara的all

解决方案1 ​​ - 直接调用BuiltIn :: All

最快的解决方案是直接调用RSpec的all方法(或者至少调用它执行的代码。

如果您使用RSpec::Matchers::BuiltIn::All.new代替all

,则期望会有效
expect(panels).to RSpec::Matchers::BuiltIn::All.new(have_css('table.orders tbody'))

解决方案2 - 重新定义所有

直接调用BuiltIn:All不能很好地阅读,因此如果经常使用可能会很烦人。另一种方法是将all方法重新定义为RSpec的all方法。为此,请添加模块和配置:

module FixAll
  def all(expected)
    RSpec::Matchers::BuiltIn::All.new(expected)
  end
end

RSpec.configure do |c|
  c.include FixAll
end

通过更改,以下行中的all将表现得像RSpec的all方法。

expect(panels).to all(have_css('table.orders tbody'))

请注意,如果你想使用Capybara的all方法,你现在总是需要使用会话来调用它(即page):

# This will work because "page.all" is used
expect(page.all('table').length).to eq(2)

# This will throw an exception since "all" is used
expect(all('table').length).to eq(2)

答案 1 :(得分:-1)

我对接受的答案采用了非常类似的方法,但在黄瓜环境中,我收到的错误是RSpec.configure不存在。另外,我想在匹配器all之外调用匹配器,以便我可以使用它们而不会发生冲突。这就是我最终的结果

# features/support/rspec_each.rb

module RSpecEach
  def each(expected)
    RSpec::Matchers::BuiltIn::All.new(expected)
  end
end

World(RSpecEach) # extends the Cucumber World environment

现在我可以做以下事情:

expect(page.all('#employees_by_dept td.counts')).to each(have_text('1'))