可以在个别规格测试中包含设置步骤吗?

时间:2012-06-03 08:52:02

标签: ruby-on-rails ruby rspec

我正在编写一个规范来测试down_vote方法。但是为了测试这个,我需要在数据库中有一个条目用于现有投票。所以我的规范看起来像这样:

describe "down_vote" do
  it "lowers vote count" do
    video = Factory.create(:video)
    user = Factory.create(:user)
    vote = Factory.vote(:vote, :voter_id => user.id, :voteable_id => video.id)

    expect do
      user.down_vote(video)
    end.to change{ Vote.count }.by 1
  end
end

写这样的规格/测试可以吗?似乎有很多我不太满意的设置,但我真的不知道有任何其他方法来测试它。

2 个答案:

答案 0 :(得分:1)

我会这样做:

let(:video) { Factory.create(:video) }
let(:user)  { Factory.create(:user)}
let(:vote)  { Factory.vote(:vote, :voter_id => user.id, :voteable_id => video.id)}
describe "down_vote" do
  it "lowers vote count" do
    vote # or use let! To have the vote created directly
    expect do
      user.down_vote(video)
    end.to change{ Vote.count }.by 1
  end
end

let超出您的规范可以重复使用

答案 1 :(得分:0)

假设您的规范按预期工作,只要不违反DRY原则,在单个测试块中使用工厂没有任何问题。如果许多测试要引用相同的对象,那么您可能希望使用RSpec letbefore块来实例化工厂对象。

您可能还想阅读“使用工厂”和“关联”的factory_girl documentation部分,看看您的特定测试是否可以:

  1. 使用#build而不是#create来避免写入数据库,
  2. 利用#association,以便您的工厂可以隐式构建/创建关联记录。
  3. 根据经验,在相关测试块内执行特定于测试的设置是很好的。重要的是避免以手动和容易出错的方式重复设置相同的数据。