[rspec-users] Problems with mock assigned to a constant

Scott Taylor mailing_lists at railsnewbie.com
Fri Jul 25 01:25:20 EDT 2008


On Jul 25, 2008, at 1:15 AM, Matt Lins wrote:

> On Thu, Jul 24, 2008 at 11:47 PM, Scott Taylor
> <mailing_lists at railsnewbie.com> wrote:
>>
>> On Jul 25, 2008, at 12:32 AM, Matt Lins wrote:
>>
>>> I suppose the way I'm defining the stubs, differs from what Dave is
>>> doing in his example.
>>>
>>> I assumed that:
>>>
>>> MyModel = mock('MyModel Class', :count => 1)
>>>
>>> was the same as:
>>>
>>> MyModel.stub!(:count).and_return(1)
>>
>> Nope.  Not even close.  Here's an equivalent of the first form:
>>
>> Object.send :remove_const, :MyModel
>> MyModel = <a mock object>
>>
>> and here's the second form:
>>
>> MyModel.instance_eval do
>> def count
>>   1
>> end
>> end
>>
>> (or:)
>>
>> MyModel.class_eval do
>> class << self
>>   def count; 1; end
>> end
>> end
>>
>> Scott
>>
>>
>
> But the stubs are defined the same way in both occurrences, no?
>
> MyModel = mock('MyModel Class', :count => 1)
>
> By passing {:count => 1} to +stubs_and_options+ I should have defined
> stubs on the mock object.  I'm using it as a shortcut for this:
>
> MyModel = mock('MyModel Class')
> MyModel.stub!(:count).and_return(1)
>
> If those example aren't doing the exact same thing I guess I'm a
> little baffled (or maybe just need to go to sleep).

The first one is redefining the constant 'MyModel'.  The second one is  
just redefining a class method (the constant isn't changing - it's  
remaining whatever it was before - say, a class)

>
>
>>>
>>>
>>> But, I'm starting to think they are not.  I haven't looked at the
>>> rSpec internals to verify, other than the parameter name:
>>>
>>> stubs_and_options+ lets you assign options and stub values
>>> at the same time. The only option available is :null_object.
>>> Anything else is treated as a stub value.
>>>
>>> So, is this problem?
>>
>> Yeah - so here are two related, but not equivalent ideas: mock  
>> objects, and
>> stubs.  A stub is just a faked out method - it can exist on a mock  
>> object (a
>> completely fake object), or on a partial mock (i.e. a real object,  
>> with a
>> method faked out).  mock('My mock") is a mock object,
>> MyRealObject.stub!(:foo) is a real object with the method foo faked  
>> out.
>>
>> What is the difference between a mock object and a fake object?  A  
>> mock
>> object will complain (read: raise an error) any time it receives a  
>> message
>> which it doesn't understand (i.e. one which hasn't been explicitly  
>> stubbed).
>> A real object will work as usual.  (A null object mock is a special  
>> type of
>> mock - one which never complains.  For now, you shouldn't worry  
>> about it).
>>
>
> Ok, I get what you saying, but as I understand it I am explicitly
> stubbing out the methods on the _mock_ object and it's still
> complaining.  If +stubs_and_options+ isn't stubbing, then what is it
> doing?

That's right - the hash to the mock method is a shorthand.  So these  
two are equivalent:

my_mock = mock('a mock')
my_mock.stub!(:foo).and_return(:bar)

AND:

my_mock = mock("a mock", {:foo => :bar})

Scott



More information about the rspec-users mailing list