Unexpected message on :attr_accessor

View: New views
11 Messages — Rating Filter:   Alert me  

Unexpected message on :attr_accessor

by schleg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This may be a dumb noob issue, but I haven't found any answers while seaching the forum--

I have a controller method

  def edit
    @user = User.find params[:id]
    @user.password_confirmation = @user.password
  end

The User class has an "attr_accessor :password_confirmation" definition (so "password_confirmation" doesn't exist in the users table). My spec has the following

  it "should find User on GET to users/edit/:id" do
    User.should_receive(:find).and_return(@user)
    @user.should_receive(:password_confirmation)
    get 'edit', :id => @user.id
  end

I am asking it to expect that I will be assigning something to that attribute in the "edit" method. Unfortunately, the spec fails with

Spec::Mocks::MockExpectationError in 'UsersController should find User on GET to users/edit/:id'
Mock 'user' received unexpected message :password_confirmation= with ("password")

Initially I thought that my "should_receive" expectation was incorrectly written, but if I comment out the attribute assignment in the controller method

...
@user = User.find params[:id]
#@user.password_confirmation = @user.password
...

then the test fails with

Spec::Mocks::MockExpectationError in 'UsersController should find User on GET to users/edit/:id'
Mock 'user' expected :password_confirmation with (any args) once, but received it 0 times

So, it seems to me that the expectation is written correctly, but something about using the attr_accessor via the mock object is causing a failure.

BTW, I am doing the following in a before(:each) block

    @user = mock("user")
    @user.stub!(:new_record?).and_return(false)
    @user.stub!(:update_attributes).and_return(true)
    @user.stub!(:password_confirmation).and_return('password')
    @user.stub!(:password).and_return('password')
    User.stub!(:new).and_return(@user)

Does anyone know what I'm missing here?

Thanks!

Re: Unexpected message on :attr_accessor

by David Chelimsky-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Dec 4, 2007 11:49 AM, schleg <schleg@...> wrote:

>
> This may be a dumb noob issue, but I haven't found any answers while seaching
> the forum--
>
> I have a controller method
>
>   def edit
>     @user = User.find params[:id]
>     @user.password_confirmation = @user.password
>   end
>
> The User class has an "attr_accessor :password_confirmation" definition (so
> "password_confirmation" doesn't exist in the users table). My spec has the
> following
>
>   it "should find User on GET to users/edit/:id" do
>     User.should_receive(:find).and_return(@user)
>     @user.should_receive(:password_confirmation)

This should be:

@user.should_receive(:password_confirmation=)

Cheers,
David

>     get 'edit', :id => @user.id
>   end
>
> I am asking it to expect that I will be assigning something to that
> attribute in the "edit" method. Unfortunately, the spec fails with
>
> Spec::Mocks::MockExpectationError in 'UsersController should find User on
> GET to users/edit/:id'
> Mock 'user' received unexpected message :password_confirmation= with
> ("password")
>
> Initially I thought that my "should_receive" expectation was incorrectly
> written, but if I comment out the attribute assignment in the controller
> method
>
> ...
> @user = User.find params[:id]
> #@user.password_confirmation = @user.password
> ...
>
> then the test fails with
>
> Spec::Mocks::MockExpectationError in 'UsersController should find User on
> GET to users/edit/:id'
> Mock 'user' expected :password_confirmation with (any args) once, but
> received it 0 times
>
> So, it seems to me that the expectation is written correctly, but something
> about using the attr_accessor via the mock object is causing a failure.
>
> BTW, I am doing the following in a before(:each) block
>
>     @user = mock("user")
>     @user.stub!(:new_record?).and_return(false)
>     @user.stub!(:update_attributes).and_return(true)
>     @user.stub!(:password_confirmation).and_return('password')
>     @user.stub!(:password).and_return('password')
>     User.stub!(:new).and_return(@user)
>
> Does anyone know what I'm missing here?
>
> Thanks!
> --
> View this message in context: http://www.nabble.com/Unexpected-message-on-%3Aattr_accessor-tf4944588.html#a14155614
> Sent from the rspec-users mailing list archive at Nabble.com.
>
> _______________________________________________
> rspec-users mailing list
> rspec-users@...
> http://rubyforge.org/mailman/listinfo/rspec-users
>
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Unexpected message on :attr_accessor

by Aslak Hellesoy :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Dec 4, 2007 8:02 PM, David Chelimsky <dchelimsky@...> wrote:

> On Dec 4, 2007 11:49 AM, schleg <schleg@...> wrote:
> >
> > This may be a dumb noob issue, but I haven't found any answers while seaching
> > the forum--
> >
> > I have a controller method
> >
> >   def edit
> >     @user = User.find params[:id]
> >     @user.password_confirmation = @user.password
> >   end
> >
> > The User class has an "attr_accessor :password_confirmation" definition (so
> > "password_confirmation" doesn't exist in the users table). My spec has the
> > following
> >
> >   it "should find User on GET to users/edit/:id" do
> >     User.should_receive(:find).and_return(@user)
> >     @user.should_receive(:password_confirmation)
>
> This should be:
>
> @user.should_receive(:password_confirmation=)
>

Lots of beginners make this mistake. Maybe RSpec's mock framework
should be smart enough to suggest this fix by itself.

Patch anyone?

Aslak

> Cheers,
> David
>
>
> >     get 'edit', :id => @user.id
> >   end
> >
> > I am asking it to expect that I will be assigning something to that
> > attribute in the "edit" method. Unfortunately, the spec fails with
> >
> > Spec::Mocks::MockExpectationError in 'UsersController should find User on
> > GET to users/edit/:id'
> > Mock 'user' received unexpected message :password_confirmation= with
> > ("password")
> >
> > Initially I thought that my "should_receive" expectation was incorrectly
> > written, but if I comment out the attribute assignment in the controller
> > method
> >
> > ...
> > @user = User.find params[:id]
> > #@user.password_confirmation = @user.password
> > ...
> >
> > then the test fails with
> >
> > Spec::Mocks::MockExpectationError in 'UsersController should find User on
> > GET to users/edit/:id'
> > Mock 'user' expected :password_confirmation with (any args) once, but
> > received it 0 times
> >
> > So, it seems to me that the expectation is written correctly, but something
> > about using the attr_accessor via the mock object is causing a failure.
> >
> > BTW, I am doing the following in a before(:each) block
> >
> >     @user = mock("user")
> >     @user.stub!(:new_record?).and_return(false)
> >     @user.stub!(:update_attributes).and_return(true)
> >     @user.stub!(:password_confirmation).and_return('password')
> >     @user.stub!(:password).and_return('password')
> >     User.stub!(:new).and_return(@user)
> >
> > Does anyone know what I'm missing here?
> >
> > Thanks!
> > --
> > View this message in context: http://www.nabble.com/Unexpected-message-on-%3Aattr_accessor-tf4944588.html#a14155614
> > Sent from the rspec-users mailing list archive at Nabble.com.
> >
> > _______________________________________________
> > rspec-users mailing list
> > rspec-users@...
> > http://rubyforge.org/mailman/listinfo/rspec-users
> >
> _______________________________________________
> rspec-users mailing list
> rspec-users@...
> http://rubyforge.org/mailman/listinfo/rspec-users
>
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Unexpected message on :attr_accessor

by Jonathan Linowes :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


>>
>> This should be:
>>
>> @user.should_receive(:password_confirmation=)
>>
>
> Lots of beginners make this mistake. Maybe RSpec's mock framework
> should be smart enough to suggest this fix by itself.
>
> Patch anyone?
>
> Aslak
>>

perhaps be even more explicit that it's an accessor, like

User.should_set(:password_confirmation)
User.should_get(:password_confirmation)

_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Unexpected message on :attr_accessor

by David Chelimsky-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Dec 4, 2007 2:54 PM, Jonathan Linowes <jonathan@...> wrote:

>
> >>
> >> This should be:
> >>
> >> @user.should_receive(:password_confirmation=)
> >>
> >
> > Lots of beginners make this mistake. Maybe RSpec's mock framework
> > should be smart enough to suggest this fix by itself.
> >
> > Patch anyone?
> >
> > Aslak
> >>
>
> perhaps be even more explicit that it's an accessor, like
>
> User.should_set(:password_confirmation)
> User.should_get(:password_confirmation)

This is silly. Mock frameworks are not there to help you learn the
language. Adding getter/setter knowledge into a framework is
completely backwards.

-1000

>
>
> _______________________________________________
> rspec-users mailing list
> rspec-users@...
> http://rubyforge.org/mailman/listinfo/rspec-users
>
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Unexpected message on :attr_accessor

by Jonathan Linowes :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

err, that suggestion was supposed to read @user.should_set...
etc

On Dec 4, 2007, at 3:54 PM, Jonathan Linowes wrote:

>
>>>
>>> This should be:
>>>
>>> @user.should_receive(:password_confirmation=)
>>>
>>
>> Lots of beginners make this mistake. Maybe RSpec's mock framework
>> should be smart enough to suggest this fix by itself.
>>
>> Patch anyone?
>>
>> Aslak
>>>
>
> perhaps be even more explicit that it's an accessor, like
>
> User.should_set(:password_confirmation)
> User.should_get(:password_confirmation)
>
> _______________________________________________
> rspec-users mailing list
> rspec-users@...
> http://rubyforge.org/mailman/listinfo/rspec-users

_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Unexpected message on :attr_accessor

by David Chelimsky-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Dec 4, 2007 3:00 PM, David Chelimsky <dchelimsky@...> wrote:

> On Dec 4, 2007 2:54 PM, Jonathan Linowes <jonathan@...> wrote:
> >
> > >>
> > >> This should be:
> > >>
> > >> @user.should_receive(:password_confirmation=)
> > >>
> > >
> > > Lots of beginners make this mistake. Maybe RSpec's mock framework
> > > should be smart enough to suggest this fix by itself.
> > >
> > > Patch anyone?
> > >
> > > Aslak
> > >>
> >
> > perhaps be even more explicit that it's an accessor, like
> >
> > User.should_set(:password_confirmation)
> > User.should_get(:password_confirmation)
>
> This is silly. Mock frameworks are not there to help you learn the
> language.

That was a knee-jerk reaction. Let me explain.

We already have should_receive(:message). :password_confirmation and
password_confirmation= are two completely different messages. So
saying should_set(:password_confirmation) hides what the message is
that you're looking for. RSpec does aim to make things readable and
consequently pleasing, but it's not here to protect you from having to
learn the language.

This is the same issue we had in rspec core w/ should equal(value).
There are 4 versions of equal in Ruby and they all have different
meanings, so we set up rspec to expose them, which means you have to
understand Ruby to understand what "should equal" means.

> Adding getter/setter knowledge into a framework is
> completely backwards.

Just following up on that thought - even though duplication is the
root of all evil in OO, so are getters and setters. They act like they
are encapsulating something, but really they encourage objects to
interact with the state of other objects instead of interacting with
the objects themselves and letting them manage their own state -
THATS's what encapsulation means - not hiding data behind a
getter/setter method. So having a first class construct in a mock
framework that encourages thinking in terms of getters and setters
seems like a step in the wrong direction.

FWIW,
David

>
> -1000
>
>
> >
> >
> > _______________________________________________
> > rspec-users mailing list
> > rspec-users@...
> > http://rubyforge.org/mailman/listinfo/rspec-users
> >
>
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Unexpected message on :attr_accessor

by schleg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks, David! Glad I'm unstuck on this :)

David Chelimsky-2 wrote:
On Dec 4, 2007 11:49 AM, schleg <schleg@gmail.com> wrote:
>
> This may be a dumb noob issue, but I haven't found any answers while seaching
> the forum--
>
> I have a controller method
>
>   def edit
>     @user = User.find params[:id]
>     @user.password_confirmation = @user.password
>   end
>
> The User class has an "attr_accessor :password_confirmation" definition (so
> "password_confirmation" doesn't exist in the users table). My spec has the
> following
>
>   it "should find User on GET to users/edit/:id" do
>     User.should_receive(:find).and_return(@user)
>     @user.should_receive(:password_confirmation)

This should be:

@user.should_receive(:password_confirmation=)

Cheers,
David

>     get 'edit', :id => @user.id
>   end
>
> I am asking it to expect that I will be assigning something to that
> attribute in the "edit" method. Unfortunately, the spec fails with
>
> Spec::Mocks::MockExpectationError in 'UsersController should find User on
> GET to users/edit/:id'
> Mock 'user' received unexpected message :password_confirmation= with
> ("password")
>
> Initially I thought that my "should_receive" expectation was incorrectly
> written, but if I comment out the attribute assignment in the controller
> method
>
> ...
> @user = User.find params[:id]
> #@user.password_confirmation = @user.password
> ...
>
> then the test fails with
>
> Spec::Mocks::MockExpectationError in 'UsersController should find User on
> GET to users/edit/:id'
> Mock 'user' expected :password_confirmation with (any args) once, but
> received it 0 times
>
> So, it seems to me that the expectation is written correctly, but something
> about using the attr_accessor via the mock object is causing a failure.
>
> BTW, I am doing the following in a before(:each) block
>
>     @user = mock("user")
>     @user.stub!(:new_record?).and_return(false)
>     @user.stub!(:update_attributes).and_return(true)
>     @user.stub!(:password_confirmation).and_return('password')
>     @user.stub!(:password).and_return('password')
>     User.stub!(:new).and_return(@user)
>
> Does anyone know what I'm missing here?
>
> Thanks!
> --
> View this message in context: http://www.nabble.com/Unexpected-message-on-%3Aattr_accessor-tf4944588.html#a14155614
> Sent from the rspec-users mailing list archive at Nabble.com.
>
> _______________________________________________
> rspec-users mailing list
> rspec-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Unexpected message on :attr_accessor

by Jonathan Linowes :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

damn, looks like I'm going to have to come up with 997 more good  
ideas just to break even
:)


On Dec 4, 2007, at 4:18 PM, David Chelimsky wrote:

>>
>> -1000
>>
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Unexpected message on :attr_accessor

by David Chelimsky-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Dec 4, 2007 9:49 PM, Jonathan Linowes <jonathan@...> wrote:
> damn, looks like I'm going to have to come up with 997 more good
> ideas just to break even
> :)

Tell you what, I'll withdraw 999 and leave it as a -1. That leaves you
at +2 I believe.

> On Dec 4, 2007, at 4:18 PM, David Chelimsky wrote:
>
> >>
> >> -1000
> >>
> _______________________________________________
> rspec-users mailing list
> rspec-users@...
> http://rubyforge.org/mailman/listinfo/rspec-users
>
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Unexpected message on :attr_accessor

by David Chelimsky-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Dec 4, 2007 9:56 PM, David Chelimsky <dchelimsky@...> wrote:
> On Dec 4, 2007 9:49 PM, Jonathan Linowes <jonathan@...> wrote:
> > damn, looks like I'm going to have to come up with 997 more good
> > ideas just to break even
> > :)
>
> Tell you what, I'll withdraw 999 and leave it as a -1. That leaves you
> at +2 I believe.

Although the 997 good ideas would be welcome.

>
>
> > On Dec 4, 2007, at 4:18 PM, David Chelimsky wrote:
> >
> > >>
> > >> -1000
> > >>
> > _______________________________________________
> > rspec-users mailing list
> > rspec-users@...
> > http://rubyforge.org/mailman/listinfo/rspec-users
> >
>
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users