Rails 4, rspec 3: model validation test
Asked Answered
S

1

15

I have an organization object that has attributes name, doing_business_as. I need to validate that the name is not the same as doing_business_as.

# app/models/organization.rb
class Organization < ActiveRecord::Base
  validate :name_different_from_doing_business_as

  def name_different_from_doing_business_as
    if name == doing_business_as
      errors.add(:doing_business_as, "cannot be same as organization name")
    end
  end
end

I have a matching rspec file that verifies this:

# spec/models/organization_spec.rb
require "rails_helper"

describe Organization do
  it "does not allow NAME and DOING_BUSINESS_AS to be the same" do
    organization = build(:organization, name: "same-name", doing_business_as: "same-name")

    expect(organization.errors[:doing_business_as].size).to eq(1)
  end
end

When I run the spec, however, it fails and this is what I get:

$ rspec spec/models/organization_spec.rb

Organization
  does not allow NAME and DOING_BUSINESS_AS to be the same (FAILED - 1)

Failures:

  1) Organization validations does not allow NAME and DOING_BUSINESS_AS to be the same
     Failure/Error: expect(organization.errors[:doing_business_as].size).to eq(1)

       expected: 1
            got: 0

       (compared using ==)
     # ./spec/models/organization_spec.rb:113:in `block (3 levels) in <top (required)>'

Finished in 0.79734 seconds (files took 3.09 seconds to load)
10 examples, 1 failure

Failed examples:

rspec ./spec/models/organization_spec.rb:110 # Organization validations does not allow NAME and DOING_BUSINESS_AS to be the same

I was expecting the spec to pass and ensure that the 2 attributes cannot be the same. In the Rails console I can mimic the expected behavior, but I can't seem to get the spec to "fail" successfully.

I also checked via the Rails Console that it works as expected:

$ rails c
> o = Organization.new(name: "same", doing_business_as: "same")
> o.valid?
  => false
> o.errors[:doing_business_as]
  => ["cannot be the same as organization name"]

So I know the functionality is there, but I can't get a workable test...

Spent answered 1/12, 2014 at 16:6 Comment(0)
F
25

You need to use build method instead of create method.

# spec/models/organization_spec.rb
require "rails_helper"

describe Organization do
  it "does not allow NAME and DOING_BUSINESS_AS to be the same" do
    organization = build(:organization, name: "same-name", doing_business_as: "same-name")
    organization.valid?
    expect(organization.errors[:doing_business_as].size).to eq(1)
  end
end

or

# spec/models/organization_spec.rb
require "rails_helper"

describe Organization do
  it "does not allow NAME and DOING_BUSINESS_AS to be the same" do
    organization = build(:organization, name: "same-name", doing_business_as: "same-name")
    expect(organization).to be_invalid
  end
end
Frontward answered 1/12, 2014 at 16:9 Comment(4)
I tried build and got past the initial error, but it won't actually register the error: rspec says "expected: 1, got: 0". When I open the Rails console and attempt this manually, it stops the record from being created and I can check on the organization.errors[:doing_busines_as] and it tells me there is 1 item. My thoughts are maybe there's something incredibly obvious that's wrong with my spec? I updated it with the build syntax.Spent
I added the rspec error output to the original question (not enough space in the comments).Spent
Okay, You can expect the result like following. expect(organization).to be_invalid or you need to call organization.valid? before expect method.Frontward
Yep, calling organization.valid? before the expect() works. I thought that the rspec build/create methods would try the validation automatically, but it appears they do not. I accepted your answer, thanks for the quick feedback and your help!Spent

© 2022 - 2024 — McMap. All rights reserved.