[rspec-users] Cucumber - stub! or mock?

Tim Glen tim at pivotib.com
Tue Sep 16 10:41:15 EDT 2008

>> I've got some code that I (mostly) inherited. It essentially has a  
>> couple of AR class methods that look for a specific record by id:
>> class Project < ActiveRecord::Base
>>  class << self
>>    def specific_project
>>      @another_specific_project ||= Project.find(10) if  
>> Project.exists?(10)
>>    end
>>    def another_specific_project
>>      @specific_project ||= Project.find(11) if Project.exists?(11)
>>    end
>>  end
>> end
>> Typically, when I've specced this code (or more accurately, code  
>> that uses it), I've stubbed out those methods to return a mocked  
>> model. Lately, I've started using cucumber and adding stories for  
>> areas we're adding features to or finding regressions in. From what  
>> I can tell, I can't stub or mock anything from within cucumber step  
>> files. Realizing that the pattern is a bit of code smell, I feel  
>> like I have two directions I could go:
>> 1. Is there a way to stub out the model to return some fixture-type  
>> records?
>> 2. Does anyone have an idea as to how we could refactor this into a  
>> better pattern? Those 2 "projects" are pretty specific to the  
>> production data and will "never be edited," but it still doesn't  
>> make me comfortable.
> If those objects are built into your system and will never, ever  
> change, I would consider storing their definition in the code rather  
> than in the database anyway.
> http://www.refactoring.com/catalog/replaceTypeCodeWithSubclasses.html
> That would get around your issues with the pristine test database  
> being different to the production / development database, and IMO  
> more clearly communicates to future developers that these objects  
> are 'special'.
> Of course it depends on how many of them there are, whether you have  
> a use case for editing them etc, but it's worth thinking about.

Thanks all for the ideas. I knew that stubbing or mocking from within  
Cucumber was the wrong direction. I started exploring going that  
direction, but all my instincts were crying out against it.

I'm going to look into either subclassing the Project model or putting  
the differences in the database itself. I've considered putting the  
differences into the data previously, but we're talking about 2  
distinct projects out of 100+. I would need 2 new columns for the data  
and they would only ever each be used for 1 project - doesn't feel  
right somehow.

Matt - in terms of subclassing it, I have the entire stable of  
projects, 1 "internal" project and 1 "slush fund" project. If I'm  
subclassing the project, I assume that I still need to have a record  
for them in the database that needs to be findable. So while the  
subclass suggestion helps, I'm not sure it gets me all the way there?  
Could very well be that I'm missing something there...

>> As for setting up the data, I tend not to use fixtures (I only want  
>> to
>> have the data created for certain tests). Instead I save the relevant
>> models in the Given steps, preparing for the feature test. If you are
>> going to repeat the given steps a lot I would extract the model set- 
>> up
>> into a ruby function and reuse this.
> You might also take a look at http://github.com/flogic/object_daddy.

For test data, I've been using the FixtureReplacement plugin rather  
than fixtures - it basically abstracts the creation and destruction of  
objects for every scenario. However, I've only been using it for about  
a week now. It works well, but I'm not married to it yet by any  
stretch. Is Object Daddy in a stable state? it looks pretty tasty, I  
have to say.

thanks again,

More information about the rspec-users mailing list