控制台说变量不是零,在测试中它是零

时间:2013-06-27 07:40:49

标签: ruby-on-rails ruby-on-rails-3 rspec

进行简单的测试:

  context "in the same board" do
    @link = FactoryGirl.create(:link_with_board, url: "www.onet.pl")
    @board = @link.board
    it "is invalid when the same url already exists" do
      expect(@board.links.build(url: "www.onet.pl")).to_not be_valid
      expect(@board.links.build(url: "http://www.onet.pl")).to_not be_valid
      expect(@board.links.build(url: "www.onet.pl/")).to_not be_valid
    end
  end

它显示了我的错误:

Failures:

  1) Link in the same board is invalid when the same url already exists
     Failure/Error: expect(@board.links.build(url: "www.onet.pl")).to_not be_valid
     NoMethodError:
       undefined method `links' for nil:NilClass
     # ./spec/models/link_spec.rb:50:in `block (3 levels) in <top (required)>'

当我在控制台中尝试相同时,一切正常。知道为什么吗?

更新

好的,我让它成功了,但问题仍然是一样的,为什么第一个不起作用?

  context "in the same board" do
    #FIX START
    before :each do
      @link = FactoryGirl.create(:link_with_board, url: "www.onet.pl")
      @board = @link.board
    end
    #FIX END
    it "is invalid when the same url already exists" do
      expect(@board.links.build(url: "www.onet.pl")).to_not be_valid
      expect(@board.links.build(url: "http://www.onet.pl")).to_not be_valid
      expect(@board.links.build(url: "www.onet.pl/")).to_not be_valid
    end
  end

2 个答案:

答案 0 :(得分:3)

您正在@link块中设置@boardcontext。这是it块的不同范围,因此当it块运行时,这些变量未定义。

在幕后,context创建了一个类,it创建了一个方法,所以你所做的与此类似:

class MyExampleGroup
  @link = FactoryGirl.create(:link_with_board, url: "www.onet.pl")
  @board = @link.board

  def it_is_invalid_sometimes
    @board.nil? # => true
  end
end

类范围中设置的实例变量在类中是可见的,但在类的实例中不可见。

当你将它们移到之前时,生成的结构更像是这样:

class MyExampleGroup
  def before
    @link = FactoryGirl.create(:link_with_board, url: "www.onet.pl")
    @board = @link.board
  end

  def it_is_invalid_sometimes
    @board.nil? # => false
  end
end

现在实例变量正在实例范围中定义,因此它们可以按预期工作。

(为了清楚起见,我略微简化:it调用创建的方法实际返回RSpec::Core::Example个对象,before块使用instance_exec在这些对象上运行。)

答案 1 :(得分:1)

如果使用简单的rails console命令启动控制台,它将连接到开发数据库(在正常设置中)。但测试是针对测试数据库运行的。

在您的测试中,创建@link

的行
@link = FactoryGirl.create(:link_with_board, url: "www.onet.pl")

您可能想要检查:link_with_board工厂的定义方式。 (可能在spec/factories/*.rb。)