进行简单的测试:
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
答案 0 :(得分:3)
您正在@link
块中设置@board
和context
。这是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
。)