Ruby on rails Rspec:后块中的测试
我有这样一个规范:Ruby on rails Rspec:后块中的测试,ruby-on-rails,rspec,refactoring,capybara,Ruby On Rails,Rspec,Refactoring,Capybara,我有这样一个规范: context 'index' do let!(:article) { create :article } subject { visit articles_path } specify do subject expect(page).to have_content(article.title) end end subject { visit articles_path } it 'has a nice title' do subje
context 'index' do
let!(:article) { create :article }
subject { visit articles_path }
specify do
subject
expect(page).to have_content(article.title)
end
end
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
但是,当我尝试像这样重构它时,它说我有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
然后运行之后的钩子吗?我很确定我以前使用过这个设置
请告诉我如何正确重构这个。谢谢
更新
我可以这样做,但我真的不喜欢:
subject do
visit articles_path
page
end
specify do
expect(subject).to have_content(article.title)
end
“after”块通常用于在执行测试示例后执行某些操作。在第二个示例中,在“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
在我看来,从您的重构尝试来看,有一点混乱
首先,您之所以看到0个示例,0个失败
,是因为您的测试中没有主题调用。这样想:
context 'index' do
let!(:article) { create :article }
subject { visit articles_path }
specify do
subject
expect(page).to have_content(article.title)
end
end
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
blocksvisit articles\u 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
您可以有不同的期望,它/指定相同上下文中的块。
使用不同的上下文指定同一功能的不同行为。
最后一步。在块之前的中对共享功能进行分组。在我们的例子中:
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
如您所见,这两个上下文运行主题,但只有第一个内容让用户登录以测试文章页面,而第二个上下文则没有。
我希望这是有用的
继续测试,很快它就会成为一种习惯,你将很容易编写测试。问题是,我有更多的上下文,它们共享相同的let/访问共享上下文。我想我可以在{expect}之后在上下文'other'中进行实际测试;结束
请查看我编辑的解决方案,我不知道您为什么要将验证代码放在after块中。在这种情况下,{login\u as:user}
将在{visit articles\u path}
之前执行,为了使您的示例生效,我必须在{login\u as:user;visit articles\u path}之前执行上下文中的
。