[rspec-users] need some advice on the best way to structure testable shared methods

Patrick J. Collins patrick at collinatorstudios.com
Mon Nov 14 19:57:57 EST 2011


So, I recognize that there are many different ways to accomplish what I am
trying to do, but none of them seem to be as elegant as I would like.

I have a few classes which need to have shared functionality...

So I could do something like this:

module NameBuilder

  def build_name(*args)
    args.shift.to_s + args.flatten.map {|component| "[#{component}]"}.join
  end

end

class Foo
  include NameBuilder

  def initialize(arg1, arg2)
    ...
  end
end

class Bar
  include NameBuilder

  def initialize(arg1, arg2)
    ...
  end
end

...

But, then I need to do something like:

shared_examples "a nameable thingie" do |obj|
  
  describe "#build_name" do
    
    it "it adds the collection of arguments to the base components and formats them for a form element name attribute" do
      obj.build_name(:lol, :lollerskates, :roflcopter).should == "lol[lollerskates][roflcopter]"
    end
    
  end

end

describe Foo do
  it_behaves_like "a nameable thingie", Foo.new(nil, nil)
end

describe Bar do
  it_behaves_like "a nameable thingie", Bar.new(nil, nil)
end

Which I don't like, mainly because Foo & Bar's initialize methods require
arguments, and I am having to do (nil, nil) which seems very uncool...

...........

So, another approach would be to do:

class Nameable

  def build_name(*args)
    args.shift.to_s + args.flatten.map {|component| "[#{component}]"}.join
  end

end

...

class Foo < Nameable
   ...
end 

class Bar < Nameable
   ...
end

And then I can have a dedicated spec for Nameable and not worry about testing
that in Foo and Bar...  But, I am not 100% crazy about that approach either.

Can anyone suggest a better way?

Thanks!

Patrick J. Collins
http://collinatorstudios.com



More information about the rspec-users mailing list