2

I am confused with testing (Rspec) a model with null: false on some attributes :

When creating a new instance with one of those attribute = nil, the new instance.valid? returns true but if I try to save it, it returns error messages on ActiveRecord::NotNullViolation. I understand it passes 'Model Validations' but fails in 'DataBase Validations'. What is a correct way to test my model then ?

RSpec.describe BusinessSetting, type: :model do
  # before :each do
  #   @business_setting = FactoryGirl.create(:business_setting)
  # end

  it "has a valid factory" do
    expect(FactoryGirl.create(:business_setting)).to be_valid
  end

  it "is invalid without a business_id" do
    expect(FactoryGirl.create(:business_setting, business_id: 
nil)).not_to be_valid
  end 

  it "is invalid without a bot_token" do
    expect(FactoryGirl.build(:business_setting, bot_token: nil)).to 
raise_error
  end  
end

Failures:

  1) BusinessSetting is invalid without a business_id

Failure/Error: expect(FactoryGirl.create(:business_setting, business_id: nil)).to raise_error

 ActiveRecord::NotNullViolation:
   Mysql2::Error: Field 'business_id' doesn't have a default value: INSERT INTO `business_settings` (`bot_token`, `employee_user_id`, `created_at`, `updated_at`, `bill_regex`, `email`, `store_code`, `name`, `description`) VALUES ('516dbe4b-9a54-47e7-be7f-9110703589e6', 25899, '2017-10-19 17:42:18', '2017-10-19 17:42:18', '^F947\\d{7}$', '[email protected]', '947', 'Nom du magasin', 'Description du magasin')
 # ./spec/models/business_setting_spec.rb:14:in `block (2 levels) in <top (required)>'
 # ------------------
 # --- Caused by: ---
 # Mysql2::Error:
 #   Field 'business_id' doesn't have a default value
 #   ./spec/models/business_setting_spec.rb:14:in `block (2 levels) in <top (required)>'

  2) BusinessSetting is invalid without a bot_token

Failure/Error: expect(FactoryGirl.build(:business_setting, bot_token: nil)).to raise_error
       expected Exception but was not given a block
 # ./spec/models/business_setting_spec.rb:18:in `block (2 levels) in <top (required)>'
2
  • 1
    Your assumption is right, you could test that it raises said exception. Ultimately you want to add validation to your model, so it fails the validation and save returns false, rather than raise a DB exception. Commented Oct 19, 2017 at 17:36
  • Thanks Leito. Using FactoryGirl.build it doesn't raise any error as it do not deal with the db (I guess). Using FactoryGirl.create the raise_error is not answered as the NotNullViolation raises before. Commented Oct 19, 2017 at 17:45

1 Answer 1

5

expect to raise_error should be used with {}

expect{FactoryGirl.create(:business_setting, business_id: nil)}.to raise_error
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.