我刚刚使用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
匹配器也可以与其他匹配器一起使用?
注意:我在这个例子中使用describe
和it
代替feature
和scenario
,因为我测试的是输出而不是用户互动场景(参见我的other question)。
答案 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'))