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
> [email protected]
> http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users