为什么我的rspec测试加倍了我的对象?

时间:2013-01-15 03:41:26

标签: ruby rspec2

这是我的代码工作但我的测试失败的情况之一,我需要知道我做错了什么?

我有一个带有all方法的Project类,它只是吐出这个类的实例:

class Project

    @@all_projects = []

    def initialize(options)
      @@all_projects << self
    end

    def self.all
    @@all_projects
  end
end

现在Project.all工作正常,但我写的规范没有。

context "manipulating projects" do
    before do
        options1 = {
            name: 'Building house'
        }

        options2 = {
            name: 'Getting a loan from the Bank'
        }

        @project1 = Project.new(options1)
        @project2 = Project.new(options2)
    end
        it "can print all projects" do
      Project.all.should eq([@project1, @project2])
    end

我得到的失败信息是:

Project manipulating projects can print all projects
     Failure/Error: Project.all.should eq([@project1, @project2])

       expected: [Building house, Getting a loan from the Bank]
            got: [Building house, Building house, Building house, Getting a loan from the Bank, Building house, Getting a loan from the Bank]

以下是要点中的完整规范:https://gist.github.com/4535863

我做错了什么?我该如何解决?

2 个答案:

答案 0 :(得分:3)

它将结果加倍,因为它为每个测试运行before块,其中类属性被修改(当两个新项目被初始化时),并且(根据{ {3}})你所指的测试是第二个。

为避免此问题,您需要在后块中重置@@all_projects

after do
  Project.class_variable_set :@@all_projects, []
end

另请参阅:gist

(感谢@ How can I clear class variables between rspec tests in ruby建议将重置代码移至after块而不是before块。)

答案 1 :(得分:1)

这不会使用before块来设置恶意的实例变量。

describe Project do
  let(:options1){ 
    {
      name: 'Building house',
      priority: 2,
      tasks: []
    }
  }
  let(:options2) {
    {
      name: 'Getting a loan from the Bank',
      priority: 3,
      tasks: []
    }
  }
  let(:project1) { Project.new(options1) }
  let(:project2) { Project.new(options2) }

  context "while starting up" do

    subject { Project.new options1 }
    its(:name) { should include('Building house') }

    its(:tasks) { should be_empty }
  end

  context "manipulating projects" do
    before :all do
      Project.all.clear
    end

    subject { Project.all }
    its(:count) { should be > 0 }

    it { should eq [project1, project2] }

  end

end