[rspec-users] How To Express Change of Associated Data

s.ross cwdinfo at gmail.com
Sun Jul 6 18:50:23 EDT 2008


On Jul 6, 2008, at 3:00 PM, Pat Maddox wrote:

> On Sun, Jul 6, 2008 at 5:43 PM, s.ross <cwdinfo at gmail.com> wrote:
>> Hello--
>>
>> I'm not sure if I'm pushing too far out of specing a given model,  
>> but here's
>> what I want to express:
>>
>> class A < AR::Base
>> has_many :bs
>>
>> def okay(segment)
>> end
>> end
>>
>> class B < AR::Base
>> belongs_to :a
>> end
>>
>> it A, "should increase the vote count for a given segment if  
>> okayed" do
>> @a = A.create(stuff)
>> @a.okay(10) # okay segment 10
>> # here's where I'm having trouble...
>> # a.bs should have one row, and it should have a segment number of  
>> 10 and
>> various other stuff should happen
>> # subsequent @a.okay with different values should transform numbers  
>> in a
>> predictable way. This is handled in
>> # the A model because the transforms occur only in Bs that belong  
>> to a
>> given A.
>> @a.bs.find_by_segment_number(10).thingie.should be(1)  # not too  
>> expressive
>> @a.okay(9)
>> @a.bs.find_by_segment_number(9).thingie.should be(1)  # still not too
>> expressive
>> @a.bs. find_by_segment_number(9).transformed_thingie.should
>> be(something_else)
>> end
>>
>> This kind of spec smells to me, yet I am having trouble figuring  
>> out how to
>> explain, using rspec, exactly what the behavior is to be in a multi- 
>> step
>> sequence.
>>
>> Anybody have thoughts regarding how this might be done better?
>
> Hi,
>
> You could do
>
> lambda {
>  @a.okay(9)
> }.should change { @a.bs.find_by_segment_number(9) }.
>  from(nil).to(1)
>
> I do wonder if you might be able to make it a bit more
> behavior-oriented, maybe something like
>
> lambda {
>  @a.okay(9)
> }.should change { @a.count_votes_for(9) }.by(1)
>
> I don't know exactly what you're trying to get at though, so I can't
> be more specific.  At any rate, does using "should change" make it
> more readable to you?

Great suggestion using from and to. I am already using the behavior- 
oriented lambda{something_or_other}.should change(B, :count).by(1) for  
the straightforward case. The more difficult case is that when that  
okay() happens, it may or may not add a row, but it does some  
transformations that cause updates to fields in all of the rows  
belonging to the A. Sorry I can't be more specific than A's and B's :)

And thanks again. Rspec rocks.


More information about the rspec-users mailing list