Ok, a bit of a clarification.  After some tinkering, I noticed the problem
wasn't originating exactly where I thought it was (the example in my
previous email doesn't actually illustrate the issue).  This is the revised
example with a bit more detail to give an example that fails.

Also, I know my example is a very silly one (defining an association between
two models by using a string makes no sense given there are many better ways
to do so).  The actual method in my code is not quite as pointless as this,
but is poorly enough constructed that I am going to change some model
associations a bit in a way that will eliminate the need for the problematic
method altogether.  Nevertheless, if one were to write very silly methods
like this, I don't understand why an error would be raise in the spec.


The Item model has a "description" field and two methods, both memoized:

  def item_user
    x = description.to_s.match(/User_(\d+)/)
    User.find(x[1]) rescue nil
  end
  memoize :item_user

  def name
    if description.to_s.match(/User_(\d+)/)
      description.gsub(x[0], item_user.username)
    else
      description
    end
  end
  memoize :name


The spec I gave in my previous email (repeated below) still fails.  But the
interesting thing is that if I take out the memoize command on the item_user
method, the spec passes.  Also, it is probably relevant to state that specs
on the item_user method all pass.

spec:

it "should substitute user's username into the right place when fetching the
item name" do
  i = Item.new(:description => 'foo User_1 bar')
  User.stub!(:find).with('1').and_return( mock_model(User, :name => 'a
name') )
  i.name.should == 'foo a name bar'
end




On Thu, Jul 23, 2009 at 6:01 PM, Barun Singh <baru...@gmail.com> wrote:

> Some of my specs fail after adding the rails "memoize" feature to model
> some model methods, producing the error "Can't modify frozen class/module"
> (these specs all passed before).  This only happens if I try to use
> "and_return" within my spec, and those returned values affect the output of
> the method.  I am not trying to change frozen values in my own code; the
> error is coming from the spec trying to change a frozen value.   Below is an
> example of the type of spec for which this problem occurs.  (This example is
> very simplified and somewhat contrived just to show the issue).  Is there a
> known problem using memoize when you have message expectations?  Any
> solutions/ best practices here?
>
> Thanks..
>
>
> Item model contains an attribute called "description" and contains this
> method:
>
>   def name
>     if x = description.to_s.match(/User_(\d+)/)
>       u = User.find(x[1])
>       description.gsub(x[0], u.username)
>     else
>       description
>     end
>   end
>
>
> spec:
>
> it "should substitute user's username into the right place when fetching
> the item name" do
>   i = Item.new(:description => 'foo User_1 bar')
>   User.stub!(:find).with('1').and_return( mock_model(User, :name => 'a
> name') )
>   i.name.should == 'foo a name bar'
> end
>
>
>
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to