RSpec - 对象*应该*创建一次,而是为每个测试创建

时间:2011-09-05 00:18:39

标签: ruby-on-rails ruby unit-testing rspec rspec2

我正在尝试为我正在开发的帮助程序构建rspec(rspec2)测试用例。这个助手基本上用“信号”对象做了一些事情。在我的应用程序中,“信号”与“作者”相关联。

我遇到的麻烦是,当我使用这样的代码进行测试时:

describe SignalHelper do
  let(:author) { Author.create(author_identifier: "foobar_identifier") }

  specify "should fail to instantiate without an author" do
    lambda { SignalHelper.new }.should raise_error
  end

  specify "should instantiate with a valid author" do
    SignalHelper.new(author)
  end
end

我发现正在创建多个作者并间接导致SignalHelper中的代码出现问题。

在所有测试运行之前,如何创建一位作者并在每次测试中使用同一作者,我该怎么办?

我认为使用let()是正确的做法,但事实并非如此。我也尝试了类似于此的代码但没有成功:

describe SignalHelper do
  let(:author) { Author.create(author_identifier: "foobar_identifier") }

  before(:all) do 
    author
  end

  specify "should fail to instantiate without an author" do
    lambda { SignalHelper.new }.should raise_error
  end

  specify "should instantiate with a valid author" do
    SignalHelper.new(author)
  end
end

谢谢!

3 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

使用#let是正确的方法,因为它确保您不在规范示例之间共享测试对象的状态。如果由于某种原因无法创建多个作者,那么只需创建一个作为ivar:

describe SignalHelper do
  before(:all) { @author = Author.create(author_identifier: "foobar_identifier") }

  specify "should fail to instantiate without an author" do
    lambda { SignalHelper.new }.should raise_error
  end

  specify "should instantiate with a valid author" do
    SignalHelper.new(@author)
  end
end

答案 2 :(得分:0)

在我的情况下,database_cleaner gem在每次测试后删除了记录,因此let()正在重新创建它们。

config.after(:each) { DatabaseCleaner.clean }