0

进行简单测试:

  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
4

2 回答 2

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

于 2013-06-27T09:30:41.243 回答
1

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

在您的测试中,创建的行@link

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

您可能想检查:link_with_board工厂是如何定义的。(可能在spec/factories/*.rb。)

于 2013-06-27T07:47:49.187 回答