【问题标题】:Rspec: tests in after blockRspec:在块后测试
【发布时间】:2014-10-18 11:12:04
【问题描述】:

我有这样的规范:

context 'index' do
  let!(:article) { create :article }
  subject { visit articles_path }

  specify do
    subject
    expect(page).to have_content(article.title)
  end
end

但是,当我尝试像这样重构它时,它说我有 0 个示例:

context 'index' do
  let!(:article) { create :article }
  subject { visit articles_path }

  context do
    after { expect(page).to have_content(article.title) }
  end

  context do
    before { login_as :user }
    after { expect(page).to have_content(article.comment) }
  end

  context do
    after {}
  end

end

不应该运行subject,然后运行after 挂钩吗?我很确定我以前使用过这个设置。

请告诉我如何正确重构它。谢谢。

更新 可以这样,但我不是很喜欢:

subject do
  visit articles_path
  page
end

specify do
  expect(subject).to have_content(article.title)
end

【问题讨论】:

    标签: ruby-on-rails rspec refactoring capybara


    【解决方案1】:

    'after' 块通常用于在执行测试示例之后执行某些操作。在您的第二个示例中,您没有在“之后”块之前执行任何测试

    我会像这样重构你的代码

    context 'index' do
      let!(:article) { create :article }
      visit articles_path
      expect(page).to_not have_content(category.title)
    end
    

    编辑

    context 'index' do
      let!(:article) { create :article }
    
      before do
        visit articles_path 
      end
    
      context do
        it "displays article's title" do
          expect(page).to have_content(article.title)
        end
      end
    
      context do
        before { login_as :user }
        it "displays article's comments" do
          expect(page).to have_content(article.comment)
        end
      end
    
      context do
        #another test
      end
    end
    

    【讨论】:

    • 问题是我有更多的上下文共享相同的let!/visit 共享上下文。我以为我可以在context 'other' do after { expect }; end 中进行实际测试
    • 请看我编辑的解决方案,我不知道你为什么要把验证码放在 after 块中。
    • 在这种情况下,before { login_as :user } 将在 before { visit articles_path } 之后执行,并且为了使您的示例正常工作,我必须在 context 块中添加 before { login_as :user; visit articles_path }
    【解决方案2】:

    在我看来,你的重构尝试有点混乱。

    首先,您看到0 examples, 0 failures 的原因是因为您的测试中没有主题调用。这样想:

    subject { visit articles_path }
    
    it 'has a nice title' do
      subject
      expect(page).to have_content(article.title)
    end
    
    it 'has a nice comment' do
      subject
      expect(page).to have_content(article.comment)
    end
    

    为了使您的期望发挥作用,您需要调用主题。事实上,你甚至可以通过在 it/specify 块中明确写入 visit articles_path 来避免使用主题

    it 'has a nice title' do
      visit articles_path
      expect(page).to have_content(article.title)
    end
    
    it 'has a nice comment' do
      visit articles_path
      expect(page).to have_content(article.comment)
    end
    

    可以使用subject { ... } 干掉共享同一主题的测试。

    其次,不要将context 块与specify/it 块混淆(记住它们是别名)。 context 是一种通过分隔不同的测试结果来使您的测试更易于理解的方法。

    subject { visit articles_path }
    
    context 'user is logged in' do
      it 'displays article's title' do
        login_as :user
        subject
    
        expect(page).to have_content(article.title)
      end
    
      it 'displays article's title' do
        login_as :user
        subject
    
        expect(page).to have_content(article.comment)
      end
    end
    
    context 'user not logged in' do
      it 'displays article's comments' do
        subject
    
        expect(page).to have_content('Log in')
      end
    end
    

    您可以有不同的期望,它/指定相同上下文中的块。 使用不同的上下文来指定相同功能的不同行为。

    最后一步。在 before 块中对共享功能进行分组。在我们的示例中:

    subject { visit articles_path }
    
    before do
      subject
    end
    
    context 'user is logged in' do
    
      before do
        login_as :user
      end
    
      it 'displays article's title' do
        expect(page).to have_content(article.title)
      end
    
      it 'displays article's title' do
        expect(page).to have_content(article.comment)
      end
    end
    
    context 'user not logged in' do
      it 'displays article's comments' do
        expect(page).to have_content('Log in')
      end
    end
    

    如您所见,两个上下文运行主题,但只有第一个内容登录用户以测试文章页面,而第二个上下文没有。 我希望这很有用。

    继续测试,很快它就会成为一种习惯,你会很容易地编写测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      相关资源
      最近更新 更多