RSpec:在不同情况下执行相同的期望

时间:2015-05-27 19:15:00

标签: rspec

我想确保我的网站上的元素仅在登录时显示。

这就是我目前实现目标的方式:

it 'displays statistics when logged in' do
  expect {
    login_as(create :user)
    refresh_page
  }.to change {
    page.has_content? 'Statistics'
  }.from(false).to true # I know, "to true" is redundant here, but I like it to be explicit
end

这有些笨拙。特别是,当规范失败时,我没有得到我在做expect(page).to have_content 'Statistics'时通常得到的错误消息,我只是得到类似"预期结果从false变为true,但是没改变"这不是很有用的信息。

我知道有共享的例子,但是对于这种情况他们感觉有点太多了。

我尝试了类似下面的内容,但也没有成功:

it 'displays statistics when logged in' do
  expect(expect_to_have_content_statistics).to raise_error

  login_as(create :user)
  refresh_page

  expect_to_have_content_statistics
end

def expect_to_have_content_statistics
  expect(page).to have_content 'Statistics'
end

有什么想法吗?我不想写两次期望,因为这很容易出错。

2 个答案:

答案 0 :(得分:1)

您正在测试两种不同的情况 - 建议将它们分开。

describe 'statistics' do

  def have_statistics
    have_content('Statistics')
  end

  before { visit_statistics_page }

  it { expect(page).to_not have_statistics }

  it 'displays statistics when logged in' do
    login_as(create :user)
    expect(page).to have_statistics
  end
end

答案 1 :(得分:0)

我会将规范拆分为两个context块,因为您正在测试两个不同的用例。此外,不是对have_content进行基于文本的硬编码page检查,您是否有某种<div><span>标记包装统计信息内容(可能是classid statistics或其他内容)?如果没有,您可能需要考虑一个,如果是,那么考虑更改您的规范以检查该选择器是否存在,具体取决于用户是否登录:

RSpec.feature 'Statistics' do
  context 'when user is not logged in' do
    before do
      visit statistics_path # or whatever path this is
    end

    it 'does not display the statistics' do
      expect(page).to_not have_selector('.statistics')
    end
  end

  context 'when user is logged in' do
    before do
      login_as(create :user)
      visit statistics_path # or whatever path this is
    end

    it 'displays the statistics' do
      expect(page).to have_selector('.statistics')
    end
  end
end