Rails 3.1,RSpec:testing模型validation
我已经开始了在Rails中使用TDD的旅程,并遇到了一个关于模型validationtesting的小问题,我似乎找不到解决scheme。 比方说,我有一个用户模型,
class User < ActiveRecord::Base validates :username, :presence => true end
和一个简单的testing
it "should require a username" do User.new(:username => "").should_not be_valid end
这正确地testing存在validation,但是如果我想更具体一点呢? 例如,在错误对象上testingfull_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不会产生描述性错误消息。 它只是说“预计有效?返回假,是真的。” 但是,第二个testing示例有一个小缺点:它使用create方法而不是新方法来获取错误对象。
我希望我的testing能够更具体地说明他们正在testing的内容,但同时不需要触摸数据库。
任何人有任何投入?
首先我想说你有一个邪恶的名字。
其次,恭喜您与ROR一起努力进入TDD。我承诺一旦您开始行动,您将不会回头。
最简单的快速和肮脏的解决scheme将是每个像这样的testing之前生成一个新的有效模型:
before(:each) do @user = User.new @user.username = "a valid username" end
但是我build议你为所有的模型设置工厂,这些模型会自动生成一个有效的模型,然后你可以混合个别的属性,看看你的validation。 我喜欢为此使用FactoryGirl :
基本上一旦你设置你的testing看起来像这样:
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起,工厂女孩的语法已经改变。 我已经修改了我的示例代码来反映这一点。
testing模型validation(以及更多的主动logging)的更简单的方法是使用像应用程序或卓越的gem。
他们将允许testing如下:
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
在新版本的rspec中,你应该使用expect来代替,否则你会得到警告:
it "should have valid factory" do expect(FactoryGirl.build(:user)).to be_valid end it "should require a username" do expect(FactoryGirl.build(:user, :username => "")).not_to be_valid end
我在传统上处理function或请求规格中的错误内容规格。 所以,例如,我有一个类似的规格,我将在下面浓缩:
特征规范示例
before(:each) { visit_order_path } scenario 'with invalid (empty) description' , :js => :true do add_empty_task #this line is defined in my spec_helper expect(page).to have_content("can't be blank")
那么,我有我的模型spectesting是否有效,但是然后我的function规范testing错误消息的确切输出。 仅供参考,这些function规格要求可以在这里find水豚。
就像@ nathanvda说的那样,我会利用Thoughtbot的Shoulda Matchers的gem。 随着摇摆,你可以用以下方式编写你的testing,以testing是否存在,以及任何自定义错误消息。
RSpec.describe User do describe 'User validations' do let(:message) { "I pitty da foo who dont enter a name" } it 'validates presence and message' do is_expected.to validate_presence_of(:name). with_message message end # shorthand syntax: it { is_expected.to validate_presence_of(:name).with_message message } end end