Rails 3.1,RSpec:测试模型验证

我已经在Rails中开始了我的TDD旅程,并且遇到了一个关于模型验证测试的小问题,我似乎找不到解决方案。 比方说,我有一个用户模型,

class User < ActiveRecord::Base
  validates :username, :presence => true
end

和一个简单的测试

it "should require a username" do
  User.new(:username => "").should_not be_valid
end

这正确地测试了存在验证,但是如果我想更具体一点呢? 例如,测试错误对象上的full_messages ..

it "should require a username" do
  user = User.create(:username => "")
  user.errors[:username].should ~= /can't be blank/
end

我对初始尝试(使用should_not be_valid)的担心是RSpec不会产生描述性错误消息。 它只是说“预计有效?返回假,是真的。” 但是,第二个测试示例有一个小缺点:它使用create方法而不是新方法来获取错误对象。

我希望我的测试能够更具体地了解他们正在测试的内容,但同时不必触摸数据库。

任何人有任何投入?


首先我想说你有一个邪恶的名字。

其次,恭喜你用ROR努力进入TDD我承诺,一旦你开始行动,你将不会回头。

最简单的快速和肮脏的解决方案将是在每次测试之前生成一个新的有效模型,如下所示:

 before(:each) do
    @user = User.new
    @user.username = "a valid username"
 end

但我建议你为所有你的模型建立工厂,这些工厂会自动为你生成一个有效的模型,然后你可以混合个别属性,看看你的验证。 我喜欢为此使用FactoryGirl:

基本上,一旦你建立起来,你的测试看起来就像这样:

it "should have valid factory" do
    FactoryGirl.build(:user).should be_valid
end

it "should require a username" do
    FactoryGirl.build(:user, :username => "").should_not be_valid
end

噢,这里是一个很好的railscast,可以解释它比我更好:

祝你好运 :)


更新:从版本3.0开始,工厂女孩的语法已经改变。 我已经修改了我的示例代码以反映这一点。


测试模型验证(以及更多的活动记录)的更简单的方法是使用像应用程序或卓越的宝石。

他们将允许测试如下:

describe User

  it { should validate_presence_of :name }

end

尝试这个:

it "should require a username" do
  user = User.create(:username => "")
  user.valid?
  user.errors.should have_key(:username)
end
链接地址: http://www.djcxy.com/p/59303.html

上一篇: Rails 3.1, RSpec: testing model validations

下一篇: rspec how to run a single test?