Ruby on rails 控制台说变量不是nil,在测试中它';零

Ruby on rails 控制台说变量不是nil,在测试中它';零,ruby-on-rails,ruby-on-rails-3,rspec,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

进行简单测试:

  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)>'

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

在测试中,创建
@链接的行:

@link=FactoryGirl.create(:链接到黑板,url:“www.onet.pl”)

您可能需要检查
:link\u with\u board
工厂是如何定义的。(可能在
spec/factories/*.rb
中)

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

在测试中,创建
@链接的行:

@link=FactoryGirl.create(:链接到黑板,url:“www.onet.pl”)

您可能需要检查
:link\u with\u board
工厂是如何定义的。(可能在
spec/factories/*.rb
中)

您正在
上下文中设置
@link
@board
。这与
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
对象,并且使用
instance\u exec
在这些对象上运行
之前的
块)

您正在
上下文中设置
@link
@board
。这与
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
对象,并且使用
instance\u exec
在这些对象上运行
之前的

RAILS\u ENV=test RAILS控制台
可以切换到测试数据库,虽然测试数据库通常是空的,因为测试是在事务内部运行的。-1:RAILS_ENV不是问题所在,这是ivar作用域问题。@Domon:我多次犯相同的范围错误,我很容易识别:P
RAILS_ENV=test RAILS console
可以切换到测试数据库,虽然测试数据库通常是空的,因为测试是在事务内部运行的。-1:RAILS_ENV不是问题所在,这是一个ivar作用域问题。@Domon:我犯了很多次相同的范围错误,我很容易识别:PUse
let
而不是实例变量。使用
let
而不是实例变量。