开发者

How do I make one line tests in Rspec without Shoulda?

开发者 https://www.devze.com 2023-02-24 06:27 出处:网络
I have a bunch of very repetitive rspec tests that all have the same format: it \"inserts the correct ATTRIBUTE_NAME\" do

I have a bunch of very repetitive rspec tests that all have the same format:

it "inserts the correct ATTRIBUTE_NAME" do
     @o.ATTRIBUTE_NAME.should eql(VALUE)
end

It would be nice if I could just make one line tests like:

compare_value(ATTRIBUTE_NAME, VALUE)

But sho开发者_JAVA百科ulda doesn't seem to be geared toward these types of tests. Are there other alternatives?


Sometimes I regret exposing subject as an end-user device. It was introduced to support extensions (like shoulda matchers), so you can write examples like:

it { should do_something }

Examples like this, however, do not read well:

it { subject.attribute.should do_something }

If you're going to use subject explicitly, and then reference it explicitly in the example, I recommend using specify instead of it:

specify { subject.attribute.should do_something }

The underlying semantics are the same, but this ^^ can be read aloud.


I would write a custom RSpec helper if you want it to read more clearly and be only 1 line. Suppose we have the following class we want to test:

class MyObject
  attr_accessor :first, :last, :phone

  def initialize first = nil, last = nil, phone = nil
    self.first = first
    self.last = last
    self.phone = phone
  end
end

We could write the following matcher:

RSpec::Matchers.define :have_value do |attribute, expected|
  match do |obj|
    obj.send(attribute) == expected
  end 

  description do
    "have value #{expected} for attribute #{attribute}" 
  end
end

Then to write the tests we could do something like:

describe MyObject do
  h = {:first => 'wes', :last => 'bailey', :phone => '111.111.1111'}

  subject { MyObject.new h[:first], h[:last], h[:phone] }

  h.each do |k,v|
    it { should have_value k, v}
  end
end

If you put all of this in a file call matcher.rb and run it the following is output:

> rspec -cfn matcher.rb 

MyObject
  should have value wes for attribute first
  should have value bailey for attribute last
  should have value 111.111.1111 for attribute phone

Finished in 0.00143 seconds
3 examples, 0 failures


I found this which works great:

specify { @o.attribute.should eql(val) }


subject { @o }
it { attribute.should == value }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号