问题
I'm trying to test the length of a zip code attribute to ensure its 5 characters long. Right now I'm testing to make sure its not blank and then too short with 4 characters and too long with 6 characters.
Is there a way to test it being exactly 5 characters? So far I've found nothing online or in the rspec book.
回答1:
If you're testing a validation on an ActiveRecord model, I recommend trying out shoulda-matchers
. It provides a bunch of useful RSpec extensions useful for Rails. You could write a simple one line spec for your zip code attribute:
describe Address do
it { should ensure_length_of(:zip_code).is_equal_to(5).with_message(/invalid/) }
end
回答2:
There is no more have
matcher in the latest major release of RSpec.
As of RSpec 3.1, the correct way to test this is :
expect("Some string".length).to be(11)
回答3:
RSpec allows this:
expect("this string").to have(5).characters
You can actually write anything instead of 'characters', it's just syntactic sugar. All that's happening is that RSpec is calling #length
on the subject.
However, from your question it sounds like you actually want to test the validation, in which case I would folow @rossta's advice.
UPDATE:
Since RSpec 3, this is no longer part of rspec-expectations, but is available as a separate gem: https://github.com/rspec/rspec-collection_matchers
回答4:
Use have_attributes
built-in matcher:
expect("90210").to have_attributes(size: 5) # passes
expect([1, 2, 3]).to have_attributes(size: 3) # passes
You can also compose it with other matchers (here with be
):
expect("abc").to have_attributes(size: (be > 2)) # passes
expect("abc").to have_attributes(size: (be > 2) & (be <= 4)) # passes
回答5:
Collection matchers (all matchers that assert against strings, hashes and arrays) have been abstracted out into a seperate gem, rspec-collection_matchers.
In order to use these matchers add this to your Gemfile
:
gem 'rspec-collection_matchers'
Or your .gemspec
if you're working on a gem:
spec.add_development_dependency 'rspec-collection_matchers'
Then, add this to your spec_helper.rb
:
require 'rspec/collection_matchers'
And then you'll be able to use collection matchers in your spec:
require spec_helper
describe 'array' do
subject { [1,2,3] }
it { is_expected.to have(3).items }
it { is_expected.to_not have(2).items }
it { is_expected.to_not have(4).items }
it { is_expected.to have_exactly(3).items }
it { is_expected.to_not have_exactly(2).items }
it { is_expected.to_not have_exactly(4).items }
it { is_expected.to have_at_least(2).items }
it { is_expected.to have_at_most(4).items }
# deliberate failures
it { is_expected.to_not have(3).items }
it { is_expected.to have(2).items }
it { is_expected.to have(4).items }
it { is_expected.to_not have_exactly(3).items }
it { is_expected.to have_exactly(2).items }
it { is_expected.to have_exactly(4).items }
it { is_expected.to have_at_least(4).items }
it { is_expected.to have_at_most(2).items }
end
Note that you can use items
and characters
interchangeably, they're just syntax-sugar, and the have
matcher, and its variants, can be used on arrays, hashes and your string.
来源:https://stackoverflow.com/questions/16113834/is-there-an-rspec-test-for-exact-length-of-an-attribute