Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby + Rspec: How should I be testing attr_accessor?

Tags:

rspec

I have a ReturnItem class.

specs:

require 'spec_helper'

describe ReturnItem do
  #is this enough?
  it { should respond_to :chosen }
  it { should respond_to :chosen= }

end

class:

class ReturnItem
  attr_accessor :chosen
end

It seems a bit tedious since attr_accessor is used in practically every class. Is there a shortcut for this in rspec to test the default functionality of a getter and setter? Or do I have to go through the process of testing the getter and setter individually and manually for every attribute?

like image 404
bigpotato Avatar asked Jun 26 '14 15:06

bigpotato


People also ask

What is the use of attr_accessor in Ruby?

attr_accessor is a shortcut method when you need both attr_reader and attr_writer This is where the attr_accessor method comes in handy and allows us to take it one step further, creating all of the getter and setter methods in a single line as follows: And that is why you will often see attr_accessor in Ruby classes! 3. Summary

How to profile your tests in RSpec?

RSpec comes with a very handy option to profile your tests. Just by passing the --profile flag you’ll be able to see how long each test takes to run & fix the really slow ones. You have learned how to write tests using the RSpec testing framework. Now it’s your turn to start writing your own test!

Where does the test code go in a Ruby file?

For other newbies struggling with constructing the Ruby files, here's a hard-won tip. The test code goes inside the describe block. For example, in book_spec.rb, put the four test blocks just before the 'end' statement that closes the 'describe Book do' block. Doesn't make much sense, but it works.

What is the best framework for testing in Ruby?

Rspec is one of the best frameworks for testing in Ruby, and there’s a ton you can do with it. To learn more, check out the Rspec website. There’s also the The Rspec book, which teaches more than just Rspec: it’s all about TDD and BDD in Ruby.


Video Answer


2 Answers

I created a custom rspec matcher for this:

spec/custom/matchers/should_have_attr_accessor.rb

RSpec::Matchers.define :have_attr_accessor do |field|
  match do |object_instance|
    object_instance.respond_to?(field) &&
      object_instance.respond_to?("#{field}=")
  end

  failure_message_for_should do |object_instance|
    "expected attr_accessor for #{field} on #{object_instance}"
  end

  failure_message_for_should_not do |object_instance|
    "expected attr_accessor for #{field} not to be defined on #{object_instance}"
  end

  description do
    "checks to see if there is an attr accessor on the supplied object"
  end
end

Then in my spec, I use it like so:

subject { described_class.new }
it { should have_attr_accessor(:foo) }
like image 127
Elliot Larson Avatar answered Oct 16 '22 12:10

Elliot Larson


This is an updated version of the previous answer using RSpec 3, replacing failure_message_for_should for failure_message and failure_message_for_should_not for failure_message_when_negated:

RSpec::Matchers.define :have_attr_accessor do |field|
  match do |object_instance|
    object_instance.respond_to?(field) &&
      object_instance.respond_to?("#{field}=")
  end

  failure_message do |object_instance|
    "expected attr_accessor for #{field} on #{object_instance}"
  end

  failure_message_when_negated do |object_instance|
    "expected attr_accessor for #{field} not to be defined on #{object_instance}"
  end

  description do
    "assert there is an attr_accessor of the given name on the supplied object"
  end
end
like image 14
Martin Streicher Avatar answered Oct 16 '22 11:10

Martin Streicher