测试和模型之间的rspec数据范围

时间:2013-12-04 16:38:14

标签: ruby-on-rails ruby rspec tdd

我正在测试类似的内容:

describe "#check_name" do
  it 'should raise ArgumentError with equal name' do
    @article = Factory.build(:article)
    @article.id = 3
    lambda { @article.check_name(@article.id) }.
      should raise_error(ArgumentError)
  end
end

模特:

def check_name(article_id)
  tocheck = Article.find_by_id(article_id)
  if self.name == tocheck.name
    raise ArgumentError, "It has the same name!!!"
  end
end

调试模型时,self的值为Factory build,没关系。但tochecknilArticle.find_by_id(article_id)是零。

如果我正在调用@article.check_name()并且模型中存在Article,那么如何查询呢?

很抱歉,也许我不了解变量的范围或测试此类代码的正确方法。

[UPDATE] 这是关于ActiveRecord的查找操作的范围。 测试这种加注的正确方法是什么?

提前致谢!!!

1 个答案:

答案 0 :(得分:2)

ActiveRecord的find操作执行数据库查找,而您的Article对象尚未保存到数据库,因此nil结果。

虽然Rails验证机制可以避免需要这样的方法,并且很难指定哪种测试方法最好而不会看到整个模型及其约束,我认为选择是:

  • 使用测试双重返回find_by_id结果,或
  • 在数据库中创建记录,而不仅仅是“构建它”,然后构建一个具有相同名称的新记录,将check_name消息发送到该新记录

后者可能看起来像:

describe "#check_name" do
  it 'should raise ArgumentError with equal name' do
    article = Factory.create(:article)
    expect { Factory.build(:article).check_name(article.id) }.to raise_error(ArgumentError)
  end
end

假设您的文章工厂对所有文章使用相同的名称。如果没有,则必须将第一篇文章的名称作为参数传递给第二篇文章的构建。