views:

182

answers:

3

What are the best practices on testing modules in rspec? I have some modules that get included in few models and for now I simply have duplicate tests for each model (with few differences). Is there a way to DRY it up?

+5  A: 

Off the top of my head, could you create a dummy class in your test script and include the module into that? Then test that the dummy class has the behaviour in the way you'd expect.

EDIT: If, as pointed out in the comments, the module expects some behaviours to be present in the class into which it's mixed, then I'd try to implement dummies of those behaviours. Just enough to make the module happy to perform its duties.

That said, I'd be a little nervous about my design when a module expects a whole lot from its host (do we say "host"?) class - If I don't already inherit from a base class or can't inject the new functionality into the inheritance tree then I think I'd be trying to minimise any such expectations that a module might have. My concern being that my design would start to develop some areas of unpleasant inflexibility.

Mike Woodhouse
What if my module depends on class having certain attributes and behavior?
Andrius
+4  A: 

What mike said. Here's a trivial example:

module code...

module Say
  def hello
    "hello"
  end
end

spec fragment...

class DummyClass
end

before(:each) do
  @dummy_class = DummyClass.new
  @dummy_class.extend(Say)
end

it "get hello string" do
  @dummy_class.hello.should == "hello"
end
Karmen Blake
That's waht I had in mind. Lovely, thanks, +1
Mike Woodhouse
+1  A: 

I found a better solution in rspec homepage. Apparently it supports shared example groups. From http://rspec.info/documentation

Shared Example Groups

You can create shared example groups and include those groups into other groups.

Suppose you have some behavior that applies to all editions of your product, both large and small.

First, factor out the “shared” behavior:

shared_examples_for "all editions" do   
  it "should behave like all editions" do   
  end 
end

then when you need define the behavior for the Large and Small editions, reference the shared behavior using the it_should_behave_like() method.

describe "SmallEdition" do  
  it_should_behave_like "all editions"
  it "should also behave like a small edition" do   
  end 
end
Andrius