On Aug 14, 2010, at 9:26 AM, Ashley Moran wrote:

> 
> On 14 Aug 2010, at 11:34, Mike Howson wrote:
> 
>> Just wondered what people thoughts are to testing module's to be
>> included in mixin's? Seems to me there are two main approaches:-
> 
> Hi Mike
> 
> I've been doing a lot of this sort of coding lately, as I've been extracting 
> duplicated code into a mini-framework based on modules.
> 
> 
>> 1. Test the behavior in a mixin object that includes the module because
>> its the behavior of the object thats important not the code structure.
>> 
>> 2. Test the module in isolation as it potentially code be included
>> anywhere.
> 
> I'm not sure I know how option 2 is even possible, unless your module is all 
> module methods, as you can't call instance methods on a module directly.
> 
> However, it's easy to do this in RSpec with some Ruby meta-magic:
> 
>  module MyModule
>    def foo
>      "bar"
>    end
>  end
> 
>  describe MyModule do
>    let(:class_with_my_module) {
>      Class.new do
>        include MyModule
>      end
>    }
> 
>    subject { class_with_my_module.new }
> 
>    its(:foo) { should eq bar }
>  end

Or:

describe M do
  it "does something" do
    host = Object.new.extend(M)
    host.some_method_defined_in_m.should do_something
  end
end

I think either approach satisfies "test the module in isolation", even though 
it's not in isolation from the behaviour of Object.

> If the best approach is 2 - to test the module in isolation and the
>> module uses instance variables or methods from the object its being
>> mixed with then we would need to create a test object in the rspec test
>> that included the module and defined the required instance variables and
>> methods. Does this lead to 1 being the best approach as we are not then
>> forced to mock up a mixin just to test the module?
> 
> I'm not 100% sure but I *think* the snippet above is an implementation of 
> what you describe here.  Please correct me if I misunderstood.
> 
> 
>> The question came about because I recently had to get an untested rails
>> module under test that was included in a number of controllers and
>> depended on 'request' and 'response'. I was then faced with either
>> testing one of the controllers that included that module but also added
>> further complexity or defining a new thin controller used solely for
>> testing the module within the spec file.
> 
> In this case, you may be able to get some mileage with the above code, but 
> using `Class.new(ActionController::Base)`.
> 
> You can test individual objects that include your module with shared 
> examples, for example:
> 
>  module Fooable
>    def foo
>      "bar"
>    end
>  end
> 
>  class Baz
>    include Fooable
> 
>    # Oops - this is overriding Fooable#foo
>    def foo
>      "quux"
>    end
>  end
> 
>  shared_examples_for "a Fooable object" do
>    # Optional
>    before(:each) do
>      unless respond_to?(:fooable)
>        raise "You must provide instance method fooable"
>      end
>    end
> 
>    it "should have a foo of 'bar'" do
>      fooable.foo.should eq "bar"
>    end
>  end
> 
>  describe Baz do
>    subject { Baz.new }
>    it_should_behave_like "a Fooable object" do
>      let(:fooable) { subject }
>    end
>  end
> 
> My recommendation at the moment is to make the shared examples work 
> fully-integrated (ie, no mocks).  I've run into issue where shared examples 
> rely on mocks, which I haven't solved yet (at least not in my code - it's my 
> next TODO).
> 
> Currently I'm doing both the above.  The isolated module spec proves the 
> module enchants objects with the correct behaviour, the shared examples 
> double-check that you haven't broken that behaviour in concrete classes.
> 
> See also the recent thread "Evaluating shared example customisation block 
> before shared block" from 30th July onwards (it goes on to talk about passing 
> parameters to shared example groups, which is possible in RSpec-2 master).
> 
> HTH
> 
> Ash
> 
> -- 
> http://www.patchspace.co.uk/
> http://www.linkedin.com/in/ashleymoran
> 
> _______________________________________________
> rspec-users mailing list
> rspec-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to