rspec fails when assigning to an ActiveRecord field

HI, I have a controller action that assigns a user_id to an event record. The app works fine from the browser. However, rspec fails and I cannot figure out why. I have several tests failing but I'll give an example created by script/generate rspec_controller. Any help will be appreciated.

RSPEC test 102 describe "with invalid params" do 103 104 it "should expose a newly created but unsaved event as @event" do 105 Event.stub!(:new).with({'these' => 'params'}).and_return(mock_event(:save => false)) 106 post :create, :event => {:these => 'params'} 107 assigns(:event).should equal(mock_event) 108 end

RSPEC Test result

     should expose a newly created but unsaved event as @event

    Mock 'Event_1039' received unexpected message :user_id= with (nil)

    /home/leo/railsprojects/trunk/memorymap/app/controllers/ events_controller.rb:44:in `create'     ./spec/controllers/events_controller_spec.rb:106:

    42 def create     43 @event = Event.new(params[:event])     44 @event.user_id = session[:user_id]     45     46 respond_to do |format|

HI, I have a controller action that assigns a user_id to an event record. The app works fine from the browser. However, rspec fails and I cannot figure out why. I have several tests failing but I'll give an example created by script/generate rspec_controller. Any help will be appreciated.

RSPEC test 102 describe "with invalid params" do 103 104 it "should expose a newly created but unsaved event as @event" do 105 Event.stub!(:new).with({'these' => 'params'}).and_return(mock_event(:save => false)) 106 post :create, :event => {:these => 'params'} 107 assigns(:event).should equal(mock_event) 108 end

RSPEC Test result

    should expose a newly created but unsaved event as @event

   Mock 'Event_1039' received unexpected message :user_id= with (nil)

This error message is telling you exactly what you need. In the controller code (below), the #create action sends the #user_id= message to @event, which is the mock_event defined in the code example (above).

The mock_event method returns a mock object, which is designed to complain when it receives messages you don't tell it to expect, and so it complains when it receives #user_id=.

To eliminate that complaint, you can either set an explicit expectation (if you think that is meaningful in your code example), or you can tell it to ignore all unexpected messages by sending it #as_null_object:

mock_event(:save => false).as_null_object

Cheers, David

Thanks, I think I understand what you are saying. When running the tests, the @event in line 43 of the controller code is replaced with the mock object. Since it is a mock object, I need to tell the test that the mock object can handle a :user_id message. Can you tell me how to do that? I tried several ways but none of them seemed to work and I couldn't find it in the documentation. If anyone has a link to info that would be awesome as I'd rather learn for myself if possible.

Thanks, I think I understand what you are saying. When running the tests, the @event in line 43 of the controller code is replaced with the mock object. Since it is a mock object, I need to tell the test that the mock object can handle a :user_id message. Can you tell me how to do that? I tried several ways but none of them seemed to work and I couldn't find it in the documentation. If anyone has a link to info that would be awesome as I'd rather learn for myself if possible.

http://rspec.info/documentation/mocks/

Cheers, David