How do I spec this following example from the Agile Rails Book listed below. I am doing a similar thing in my controller and when I attempted to change it to the collection way of doing the find I am unable to get my spec to pass though I know it is working fine as my cucumber features are passing old rails way: def show @order = Order.find(params[:id]) end new rails way collection-based: def show id = params[:id] @order = @user.orders.find(id) rescue redirect_to :action => "index" end
On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkirwan at gmail.com> wrote:> How do I spec this following example from the Agile Rails Book listed > below. I am doing a similar thing in my controller and when I > attempted to change it to the collection way of doing the find I am > unable to get my spec to pass though I know it is working fine as my > cucumber features are passing > > old rails way: > > def show > @order = Order.find(params[:id]) > end > > new rails way collection-based: > > def show > id = params[:id] > @order = @user.orders.find(id)This code is inherently untestable in an isolated/granular way. Your options are: * write higher level specs that use real data * pros: simplicity and clarity in both code and specs * cons: brittle due to runtime dependency on correct models, runs slow * write a very invasive spec with complex setup and instance_eval to set up the @user * pros: runs fast, no runtime dependency on correct models * cons: brittle due to dependency on internals, complex * refactor the code to make it easier to spec * pros: more highly decoupled code, simpler specs, fast * cons: more work up front, may disregard some of what Rails has to offer Note that the first two options are both brittle, but for different reasons. The first is brittle due to a runtime dependency. That means that when you run the spec the model has to be working correctly for the spec to pass, and a failure could be due to a problem in the model or in the controller. The second is due to a code dependency. That means that when you want to change this code, the spec will have to change as well. This is true of any case in which you use mocks or stubs to varying degrees, and that comes with its own tradeoffs. In this case, the necessary stubbing would be complex and invasive enough that it would be a concern to me. Getting to your original question - what does your spec look like now, and what failure message are you getting? Cheers, David> rescue > redirect_to :action => "index" > end > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
My spec is a messed up because I have tried everything I can think of to mock but this is what I have for the show method. The @user instance is setup in the login_and_before_filter_pass macros with the following: @user = mock_model(Person, :null_object => true) The error I keep receiving is that assigns[:letter].should equal @letter keeps return that it is expecting a Person object instead of a Letter object. The only way I can get it to pass is by putting @user.letters.should_receive(:find).with("1").and_return(@letter) directly in the "should assign the found letter for the view" I feel like I must be missing something about how stubbing and mocking work # Get /admin/letters/1 def show id = params[:id] @letter = @user.letters.find(id) end describe Admin::LettersController, "SHOW GET /admin/letters/1" do before(:each) do @user.letters.should_receive(:find).with("1").and_return(@letter) end def do_get put :show, {:id => "1"}, @session end login_and_before_filter_pass(:filter => :admin_only, :request_method => :get, :action => :show, :parameters => {:cas_user => ''ak730''}) it "should be successful" do do_get response.should be_success end it "should find the letter requested" do @user.letters.should_receive(:find).with("1").and_return(@letter) puts(@letter) do_get end it "should assign the found letter for the view" do # uncommenting will allow to pass # @user.letters.should_receive(:find).with("1").and_return (@letter) do_get assigns[:letter].should equal(@letter) end it "should render show template" do do_get response.should render_template("show") end end On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote:> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: > > How do I spec this following example from the Agile Rails Book listed > > below. I am doing a similar thing in my controller and when I > > attempted to change it to the collection way of doing the find I am > > unable to get my spec to pass though I know it is working fine as my > > cucumber features are passing > > > old rails way: > > > def show > > @order = Order.find(params[:id]) > > end > > > new rails way collection-based: > > > def show > > id = params[:id] > > @order = @user.orders.find(id) > > This code is inherently untestable in an isolated/granular way. Your > options are: > > * write higher level specs that use real data > ? * pros: simplicity and clarity in both code and specs > ? * cons: brittle due to runtime dependency on correct models, runs slow > > * write a very invasive spec with complex setup and instance_eval to > set up the @user > ? * pros: runs fast, no runtime dependency on correct models > ? * cons: brittle due to dependency on internals, complex > > * refactor the code to make it easier to spec > ? * pros: more highly decoupled code, simpler specs, fast > ? * cons: more work up front, may disregard some of what Rails has to offer > > Note that the first two options are both brittle, but for different > reasons. The first is brittle due to a runtime dependency. That means > that when you run the spec the model has to be working correctly for > the spec to pass, and a failure could be due to a problem in the model > or in the controller. > > The second is due to a code dependency. That means that when you want > to change this code, the spec will have to change as well. This is > true of any case in which you use mocks or stubs to varying degrees, > and that comes with its own tradeoffs. In this case, the necessary > stubbing would be complex and invasive enough that it would be a > concern to me. > > Getting to your original question - what does your spec look like now, > and what failure message are you getting? > > Cheers, > David > > > rescue > > redirect_to :action => "index" > > end > > _______________________________________________ > > rspec-users mailing list > > rspec-us... at rubyforge.org > >http://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkirwan at gmail.com> wrote:> My spec is a messed up because I have tried everything I can think of > to mock but this is what I have for the show method. The @user > instance is setup in the login_and_before_filter_pass macros with the > following: @user = mock_model(Person, :null_object => true) > > The error I keep receiving is that assigns[:letter].should equal > @letter keeps return that it is expecting a Person object instead of a > Letter object. The only way I can get it to pass is by putting > @user.letters.should_receive(:find).with("1").and_return(@letter) > directly in the "should assign the found letter for the view" > > I feel like I must be missing something about how stubbing and mocking > work > > > ?# Get /admin/letters/1 > ?def show > ? ?id = params[:id] > ? ?@letter = ?@user.letters.find(id) > ?end > > > describe Admin::LettersController, "SHOW GET /admin/letters/1" do > > ?before(:each) do > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter)This @user is an instance variable in the spec, and is not the same @user that is in the controller. HTH, David> ?end > > ?def do_get > ? ?put :show, {:id => "1"}, @session > ?end > > ?login_and_before_filter_pass(:filter => :admin_only, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) > > ?it "should be successful" do > ? ?do_get > ? ?response.should be_success > ?end > > ?it "should find the letter requested" do > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > ? ?puts(@letter) > ? ?do_get > ?end > > ?it "should assign the found letter for the view" do > ? ?# uncommenting will allow to pass > ? ?# @user.letters.should_receive(:find).with("1").and_return > (@letter) > ? ?do_get > ? ?assigns[:letter].should equal(@letter) > ?end > > ?it "should render show template" do > ? ?do_get > ? ?response.should render_template("show") > ?end > > end > > > > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: >> > How do I spec this following example from the Agile Rails Book listed >> > below. I am doing a similar thing in my controller and when I >> > attempted to change it to the collection way of doing the find I am >> > unable to get my spec to pass though I know it is working fine as my >> > cucumber features are passing >> >> > old rails way: >> >> > def show >> > @order = Order.find(params[:id]) >> > end >> >> > new rails way collection-based: >> >> > def show >> > id = params[:id] >> > @order = @user.orders.find(id) >> >> This code is inherently untestable in an isolated/granular way. Your >> options are: >> >> * write higher level specs that use real data >> ? * pros: simplicity and clarity in both code and specs >> ? * cons: brittle due to runtime dependency on correct models, runs slow >> >> * write a very invasive spec with complex setup and instance_eval to >> set up the @user >> ? * pros: runs fast, no runtime dependency on correct models >> ? * cons: brittle due to dependency on internals, complex >> >> * refactor the code to make it easier to spec >> ? * pros: more highly decoupled code, simpler specs, fast >> ? * cons: more work up front, may disregard some of what Rails has to offer >> >> Note that the first two options are both brittle, but for different >> reasons. The first is brittle due to a runtime dependency. That means >> that when you run the spec the model has to be working correctly for >> the spec to pass, and a failure could be due to a problem in the model >> or in the controller. >> >> The second is due to a code dependency. That means that when you want >> to change this code, the spec will have to change as well. This is >> true of any case in which you use mocks or stubs to varying degrees, >> and that comes with its own tradeoffs. In this case, the necessary >> stubbing would be complex and invasive enough that it would be a >> concern to me. >> >> Getting to your original question - what does your spec look like now, >> and what failure message are you getting? >> >> Cheers, >> David >> >> > rescue >> > redirect_to :action => "index" >> > end >> > _______________________________________________ >> > rspec-users mailing list >> > rspec-us... at rubyforge.org >> >http://rubyforge.org/mailman/listinfo/rspec-users >> >> _______________________________________________ >> rspec-users mailing list >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Thanks for the help but I guess I am not getting something. How is @user= = mock_model(Person) and different then the following code: message = mock_model(Message) Message.stub!(:new).and_return message message.should_receive(:save) post :create def create message = Message.new params[:new] message.save end I guess I don''t understand why assigns[:letter] is expecting a Person instance instead of a Letter instance On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote:> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: > > My spec is a messed up because I have tried everything I can think of > > to mock but this is what I have for the show method. The @user > > instance is setup in the login_and_before_filter_pass macros with the > > following: @user = mock_model(Person, :null_object => true) > > > The error I keep receiving is that assigns[:letter].should equal > > @letter keeps return that it is expecting a Person object instead of a > > Letter object. The only way I can get it to pass is by putting > > @user.letters.should_receive(:find).with("1").and_return(@letter) > > directly in the "should assign the found letter for the view" > > > I feel like I must be missing something about how stubbing and mocking > > work > > > ?# Get /admin/letters/1 > > ?def show > > ? ?id = params[:id] > > ? ?@letter = ?@user.letters.find(id) > > ?end > > > describe Admin::LettersController, "SHOW GET /admin/letters/1" do > > > ?before(:each) do > > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > > This @user is an instance variable in the spec, and is not the same > @user that is in the controller. > > HTH, > David > > > > > > > ?end > > > ?def do_get > > ? ?put :show, {:id => "1"}, @session > > ?end > > > ?login_and_before_filter_pass(:filter => :admin_only, > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) > > > ?it "should be successful" do > > ? ?do_get > > ? ?response.should be_success > > ?end > > > ?it "should find the letter requested" do > > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > > ? ?puts(@letter) > > ? ?do_get > > ?end > > > ?it "should assign the found letter for the view" do > > ? ?# uncommenting will allow to pass > > ? ?# @user.letters.should_receive(:find).with("1").and_return > > (@letter) > > ? ?do_get > > ? ?assigns[:letter].should equal(@letter) > > ?end > > > ?it "should render show template" do > > ? ?do_get > > ? ?response.should render_template("show") > > ?end > > > end > > > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: > >> > How do I spec this following example from the Agile Rails Book listed > >> > below. I am doing a similar thing in my controller and when I > >> > attempted to change it to the collection way of doing the find I am > >> > unable to get my spec to pass though I know it is working fine as my > >> > cucumber features are passing > > >> > old rails way: > > >> > def show > >> > @order = Order.find(params[:id]) > >> > end > > >> > new rails way collection-based: > > >> > def show > >> > id = params[:id] > >> > @order = @user.orders.find(id) > > >> This code is inherently untestable in an isolated/granular way. Your > >> options are: > > >> * write higher level specs that use real data > >> ? * pros: simplicity and clarity in both code and specs > >> ? * cons: brittle due to runtime dependency on correct models, runs slow > > >> * write a very invasive spec with complex setup and instance_eval to > >> set up the @user > >> ? * pros: runs fast, no runtime dependency on correct models > >> ? * cons: brittle due to dependency on internals, complex > > >> * refactor the code to make it easier to spec > >> ? * pros: more highly decoupled code, simpler specs, fast > >> ? * cons: more work up front, may disregard some of what Rails has to offer > > >> Note that the first two options are both brittle, but for different > >> reasons. The first is brittle due to a runtime dependency. That means > >> that when you run the spec the model has to be working correctly for > >> the spec to pass, and a failure could be due to a problem in the model > >> or in the controller. > > >> The second is due to a code dependency. That means that when you want > >> to change this code, the spec will have to change as well. This is > >> true of any case in which you use mocks or stubs to varying degrees, > >> and that comes with its own tradeoffs. In this case, the necessary > >> stubbing would be complex and invasive enough that it would be a > >> concern to me. > > >> Getting to your original question - what does your spec look like now, > >> and what failure message are you getting? > > >> Cheers, > >> David > > >> > rescue > >> > redirect_to :action => "index" > >> > end > >> > _______________________________________________ > >> > rspec-users mailing list > >> > rspec-us... at rubyforge.org > >> >http://rubyforge.org/mailman/listinfo/rspec-users > > >> _______________________________________________ > >> rspec-users mailing list > >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > > rspec-users mailing list > > rspec-us... at rubyforge.org > >http://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkirwan at gmail.com> wrote:> Thanks for the help but I guess I am not getting something. How is > @user= = mock_model(Person) and different then the following code:This is assigning the mock_model(Person) to a @user instance variable in the spec. This is not the same user that is in the controller.> message = mock_model(Message) > Message.stub!(:new).and_return message > message.should_receive(:save) > post :createThis creates a mock_model(Message) and then tells Message to return it when it receives :new, therefore message in the spec is the same object as Message.new in the controller.> def create > message = Message.new params[:new] > message.save > end > I guess I don''t understand why assigns[:letter] is expecting a Person > instance instead of a Letter instanceI''m not clear on what you mean by this. Would you please post the full error message (either here or in a pastie or gist)?> > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: >> > My spec is a messed up because I have tried everything I can think of >> > to mock but this is what I have for the show method. The @user >> > instance is setup in the login_and_before_filter_pass macros with the >> > following: @user = mock_model(Person, :null_object => true) >> >> > The error I keep receiving is that assigns[:letter].should equal >> > @letter keeps return that it is expecting a Person object instead of a >> > Letter object. The only way I can get it to pass is by putting >> > @user.letters.should_receive(:find).with("1").and_return(@letter) >> > directly in the "should assign the found letter for the view" >> >> > I feel like I must be missing something about how stubbing and mocking >> > work >> >> > ?# Get /admin/letters/1 >> > ?def show >> > ? ?id = params[:id] >> > ? ?@letter = ?@user.letters.find(id) >> > ?end >> >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do >> >> > ?before(:each) do >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) >> >> This @user is an instance variable in the spec, and is not the same >> @user that is in the controller. >> >> HTH, >> David >> >> >> >> >> >> > ?end >> >> > ?def do_get >> > ? ?put :show, {:id => "1"}, @session >> > ?end >> >> > ?login_and_before_filter_pass(:filter => :admin_only, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) >> >> > ?it "should be successful" do >> > ? ?do_get >> > ? ?response.should be_success >> > ?end >> >> > ?it "should find the letter requested" do >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) >> > ? ?puts(@letter) >> > ? ?do_get >> > ?end >> >> > ?it "should assign the found letter for the view" do >> > ? ?# uncommenting will allow to pass >> > ? ?# @user.letters.should_receive(:find).with("1").and_return >> > (@letter) >> > ? ?do_get >> > ? ?assigns[:letter].should equal(@letter) >> > ?end >> >> > ?it "should render show template" do >> > ? ?do_get >> > ? ?response.should render_template("show") >> > ?end >> >> > end >> >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: >> >> > How do I spec this following example from the Agile Rails Book listed >> >> > below. I am doing a similar thing in my controller and when I >> >> > attempted to change it to the collection way of doing the find I am >> >> > unable to get my spec to pass though I know it is working fine as my >> >> > cucumber features are passing >> >> >> > old rails way: >> >> >> > def show >> >> > @order = Order.find(params[:id]) >> >> > end >> >> >> > new rails way collection-based: >> >> >> > def show >> >> > id = params[:id] >> >> > @order = @user.orders.find(id) >> >> >> This code is inherently untestable in an isolated/granular way. Your >> >> options are: >> >> >> * write higher level specs that use real data >> >> ? * pros: simplicity and clarity in both code and specs >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow >> >> >> * write a very invasive spec with complex setup and instance_eval to >> >> set up the @user >> >> ? * pros: runs fast, no runtime dependency on correct models >> >> ? * cons: brittle due to dependency on internals, complex >> >> >> * refactor the code to make it easier to spec >> >> ? * pros: more highly decoupled code, simpler specs, fast >> >> ? * cons: more work up front, may disregard some of what Rails has to offer >> >> >> Note that the first two options are both brittle, but for different >> >> reasons. The first is brittle due to a runtime dependency. That means >> >> that when you run the spec the model has to be working correctly for >> >> the spec to pass, and a failure could be due to a problem in the model >> >> or in the controller. >> >> >> The second is due to a code dependency. That means that when you want >> >> to change this code, the spec will have to change as well. This is >> >> true of any case in which you use mocks or stubs to varying degrees, >> >> and that comes with its own tradeoffs. In this case, the necessary >> >> stubbing would be complex and invasive enough that it would be a >> >> concern to me. >> >> >> Getting to your original question - what does your spec look like now, >> >> and what failure message are you getting? >> >> >> Cheers, >> >> David >> >> >> > rescue >> >> > redirect_to :action => "index" >> >> > end >> >> > _______________________________________________ >> >> > rspec-users mailing list >> >> > rspec-us... at rubyforge.org >> >> >http://rubyforge.org/mailman/listinfo/rspec-users >> >> >> _______________________________________________ >> >> rspec-users mailing list >> >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users >> > _______________________________________________ >> > rspec-users mailing list >> > rspec-us... at rubyforge.org >> >http://rubyforge.org/mailman/listinfo/rspec-users >> >> _______________________________________________ >> rspec-users mailing list >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Okay I get the "and_return" part now thanks. Here is the error http://gist.github.com/152061 On Jul 22, 11:39?am, David Chelimsky <dchelim... at gmail.com> wrote:> On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkir... at gmail.com> wrote: > > Thanks for the help but I guess I am not getting something. How is > > @user= = mock_model(Person) and different then the following code: > > This is assigning the mock_model(Person) to a @user instance variable > in the spec. This is not the same user that is in the controller. > > > message = mock_model(Message) > > Message.stub!(:new).and_return message > > message.should_receive(:save) > > post :create > > This creates a mock_model(Message) and then tells Message to return it > when it receives :new, therefore message in the spec is the same > object as Message.new in the controller. > > > def create > > message = Message.new params[:new] > > message.save > > end > > I guess I don''t understand why assigns[:letter] is expecting a Person > > instance instead of a Letter instance > > I''m not clear on what you mean by this. Would you please post the full > error message (either here or in a pastie or gist)? > > > > > > > > > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: > >> > My spec is a messed up because I have tried everything I can think of > >> > to mock but this is what I have for the show method. The @user > >> > instance is setup in the login_and_before_filter_pass macros with the > >> > following: @user = mock_model(Person, :null_object => true) > > >> > The error I keep receiving is that assigns[:letter].should equal > >> > @letter keeps return that it is expecting a Person object instead of a > >> > Letter object. The only way I can get it to pass is by putting > >> > @user.letters.should_receive(:find).with("1").and_return(@letter) > >> > directly in the "should assign the found letter for the view" > > >> > I feel like I must be missing something about how stubbing and mocking > >> > work > > >> > ?# Get /admin/letters/1 > >> > ?def show > >> > ? ?id = params[:id] > >> > ? ?@letter = ?@user.letters.find(id) > >> > ?end > > >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do > > >> > ?before(:each) do > >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > > >> This @user is an instance variable in the spec, and is not the same > >> @user that is in the controller. > > >> HTH, > >> David > > >> > ?end > > >> > ?def do_get > >> > ? ?put :show, {:id => "1"}, @session > >> > ?end > > >> > ?login_and_before_filter_pass(:filter => :admin_only, > >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, > >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, > >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) > > >> > ?it "should be successful" do > >> > ? ?do_get > >> > ? ?response.should be_success > >> > ?end > > >> > ?it "should find the letter requested" do > >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > >> > ? ?puts(@letter) > >> > ? ?do_get > >> > ?end > > >> > ?it "should assign the found letter for the view" do > >> > ? ?# uncommenting will allow to pass > >> > ? ?# @user.letters.should_receive(:find).with("1").and_return > >> > (@letter) > >> > ? ?do_get > >> > ? ?assigns[:letter].should equal(@letter) > >> > ?end > > >> > ?it "should render show template" do > >> > ? ?do_get > >> > ? ?response.should render_template("show") > >> > ?end > > >> > end > > >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: > >> >> > How do I spec this following example from the Agile Rails Book listed > >> >> > below. I am doing a similar thing in my controller and when I > >> >> > attempted to change it to the collection way of doing the find I am > >> >> > unable to get my spec to pass though I know it is working fine as my > >> >> > cucumber features are passing > > >> >> > old rails way: > > >> >> > def show > >> >> > @order = Order.find(params[:id]) > >> >> > end > > >> >> > new rails way collection-based: > > >> >> > def show > >> >> > id = params[:id] > >> >> > @order = @user.orders.find(id) > > >> >> This code is inherently untestable in an isolated/granular way. Your > >> >> options are: > > >> >> * write higher level specs that use real data > >> >> ? * pros: simplicity and clarity in both code and specs > >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow > > >> >> * write a very invasive spec with complex setup and instance_eval to > >> >> set up the @user > >> >> ? * pros: runs fast, no runtime dependency on correct models > >> >> ? * cons: brittle due to dependency on internals, complex > > >> >> * refactor the code to make it easier to spec > >> >> ? * pros: more highly decoupled code, simpler specs, fast > >> >> ? * cons: more work up front, may disregard some of what Rails has to offer > > >> >> Note that the first two options are both brittle, but for different > >> >> reasons. The first is brittle due to a runtime dependency. That means > >> >> that when you run the spec the model has to be working correctly for > >> >> the spec to pass, and a failure could be due to a problem in the model > >> >> or in the controller. > > >> >> The second is due to a code dependency. That means that when you want > >> >> to change this code, the spec will have to change as well. This is > >> >> true of any case in which you use mocks or stubs to varying degrees, > >> >> and that comes with its own tradeoffs. In this case, the necessary > >> >> stubbing would be complex and invasive enough that it would be a > >> >> concern to me. > > >> >> Getting to your original question - what does your spec look like now, > >> >> and what failure message are you getting? > > >> >> Cheers, > >> >> David > > >> >> > rescue > >> >> > redirect_to :action => "index" > >> >> > end > >> >> > _______________________________________________ > >> >> > rspec-users mailing list > >> >> > rspec-us... at rubyforge.org > >> >> >http://rubyforge.org/mailman/listinfo/rspec-users > > >> >> _______________________________________________ > >> >> rspec-users mailing list > >> >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > >> > _______________________________________________ > >> > rspec-users mailing list > >> > rspec-us... at rubyforge.org > >> >http://rubyforge.org/mailman/listinfo/rspec-users > > >> _______________________________________________ > >> rspec-users mailing list > >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > > rspec-users mailing list > > rspec-us... at rubyforge.org > >http://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
thanks, I understand now the ".and_return" part. Here is the failure I am receiving http://gist.github.com/152061 On Jul 22, 11:39?am, David Chelimsky <dchelim... at gmail.com> wrote:> On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkir... at gmail.com> wrote: > > Thanks for the help but I guess I am not getting something. How is > > @user= = mock_model(Person) and different then the following code: > > This is assigning the mock_model(Person) to a @user instance variable > in the spec. This is not the same user that is in the controller. > > > message = mock_model(Message) > > Message.stub!(:new).and_return message > > message.should_receive(:save) > > post :create > > This creates a mock_model(Message) and then tells Message to return it > when it receives :new, therefore message in the spec is the same > object as Message.new in the controller. > > > def create > > message = Message.new params[:new] > > message.save > > end > > I guess I don''t understand why assigns[:letter] is expecting a Person > > instance instead of a Letter instance > > I''m not clear on what you mean by this. Would you please post the full > error message (either here or in a pastie or gist)? > > > > > > > > > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: > >> > My spec is a messed up because I have tried everything I can think of > >> > to mock but this is what I have for the show method. The @user > >> > instance is setup in the login_and_before_filter_pass macros with the > >> > following: @user = mock_model(Person, :null_object => true) > > >> > The error I keep receiving is that assigns[:letter].should equal > >> > @letter keeps return that it is expecting a Person object instead of a > >> > Letter object. The only way I can get it to pass is by putting > >> > @user.letters.should_receive(:find).with("1").and_return(@letter) > >> > directly in the "should assign the found letter for the view" > > >> > I feel like I must be missing something about how stubbing and mocking > >> > work > > >> > ?# Get /admin/letters/1 > >> > ?def show > >> > ? ?id = params[:id] > >> > ? ?@letter = ?@user.letters.find(id) > >> > ?end > > >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do > > >> > ?before(:each) do > >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > > >> This @user is an instance variable in the spec, and is not the same > >> @user that is in the controller. > > >> HTH, > >> David > > >> > ?end > > >> > ?def do_get > >> > ? ?put :show, {:id => "1"}, @session > >> > ?end > > >> > ?login_and_before_filter_pass(:filter => :admin_only, > >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, > >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, > >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) > > >> > ?it "should be successful" do > >> > ? ?do_get > >> > ? ?response.should be_success > >> > ?end > > >> > ?it "should find the letter requested" do > >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > >> > ? ?puts(@letter) > >> > ? ?do_get > >> > ?end > > >> > ?it "should assign the found letter for the view" do > >> > ? ?# uncommenting will allow to pass > >> > ? ?# @user.letters.should_receive(:find).with("1").and_return > >> > (@letter) > >> > ? ?do_get > >> > ? ?assigns[:letter].should equal(@letter) > >> > ?end > > >> > ?it "should render show template" do > >> > ? ?do_get > >> > ? ?response.should render_template("show") > >> > ?end > > >> > end > > >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: > >> >> > How do I spec this following example from the Agile Rails Book listed > >> >> > below. I am doing a similar thing in my controller and when I > >> >> > attempted to change it to the collection way of doing the find I am > >> >> > unable to get my spec to pass though I know it is working fine as my > >> >> > cucumber features are passing > > >> >> > old rails way: > > >> >> > def show > >> >> > @order = Order.find(params[:id]) > >> >> > end > > >> >> > new rails way collection-based: > > >> >> > def show > >> >> > id = params[:id] > >> >> > @order = @user.orders.find(id) > > >> >> This code is inherently untestable in an isolated/granular way. Your > >> >> options are: > > >> >> * write higher level specs that use real data > >> >> ? * pros: simplicity and clarity in both code and specs > >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow > > >> >> * write a very invasive spec with complex setup and instance_eval to > >> >> set up the @user > >> >> ? * pros: runs fast, no runtime dependency on correct models > >> >> ? * cons: brittle due to dependency on internals, complex > > >> >> * refactor the code to make it easier to spec > >> >> ? * pros: more highly decoupled code, simpler specs, fast > >> >> ? * cons: more work up front, may disregard some of what Rails has to offer > > >> >> Note that the first two options are both brittle, but for different > >> >> reasons. The first is brittle due to a runtime dependency. That means > >> >> that when you run the spec the model has to be working correctly for > >> >> the spec to pass, and a failure could be due to a problem in the model > >> >> or in the controller. > > >> >> The second is due to a code dependency. That means that when you want > >> >> to change this code, the spec will have to change as well. This is > >> >> true of any case in which you use mocks or stubs to varying degrees, > >> >> and that comes with its own tradeoffs. In this case, the necessary > >> >> stubbing would be complex and invasive enough that it would be a > >> >> concern to me. > > >> >> Getting to your original question - what does your spec look like now, > >> >> and what failure message are you getting? > > >> >> Cheers, > >> >> David > > >> >> > rescue > >> >> > redirect_to :action => "index" > >> >> > end > >> >> > _______________________________________________ > >> >> > rspec-users mailing list > >> >> > rspec-us... at rubyforge.org > >> >> >http://rubyforge.org/mailman/listinfo/rspec-users > > >> >> _______________________________________________ > >> >> rspec-users mailing list > >> >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > >> > _______________________________________________ > >> > rspec-users mailing list > >> > rspec-us... at rubyforge.org > >> >http://rubyforge.org/mailman/listinfo/rspec-users > > >> _______________________________________________ > >> rspec-users mailing list > >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > > rspec-users mailing list > > rspec-us... at rubyforge.org > >http://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
On Wed, Jul 22, 2009 at 10:52 AM, amkirwan<amkirwan at gmail.com> wrote:> Okay I get the "and_return" part now thanks. > > Here is the error > > http://gist.github.com/152061Well, the error seems quite clear. It''s expecting a Letter and gets a Person. I know you''ve posted bits of the code in this thread, but would you mind posting the entire spec and controller code in a gist? At least the code related to the show action. Thanks, David> > On Jul 22, 11:39?am, David Chelimsky <dchelim... at gmail.com> wrote: >> On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkir... at gmail.com> wrote: >> > Thanks for the help but I guess I am not getting something. How is >> > @user= = mock_model(Person) and different then the following code: >> >> This is assigning the mock_model(Person) to a @user instance variable >> in the spec. This is not the same user that is in the controller. >> >> > message = mock_model(Message) >> > Message.stub!(:new).and_return message >> > message.should_receive(:save) >> > post :create >> >> This creates a mock_model(Message) and then tells Message to return it >> when it receives :new, therefore message in the spec is the same >> object as Message.new in the controller. >> >> > def create >> > message = Message.new params[:new] >> > message.save >> > end >> > I guess I don''t understand why assigns[:letter] is expecting a Person >> > instance instead of a Letter instance >> >> I''m not clear on what you mean by this. Would you please post the full >> error message (either here or in a pastie or gist)? >> >> >> >> >> >> >> >> > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: >> >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: >> >> > My spec is a messed up because I have tried everything I can think of >> >> > to mock but this is what I have for the show method. The @user >> >> > instance is setup in the login_and_before_filter_pass macros with the >> >> > following: @user = mock_model(Person, :null_object => true) >> >> >> > The error I keep receiving is that assigns[:letter].should equal >> >> > @letter keeps return that it is expecting a Person object instead of a >> >> > Letter object. The only way I can get it to pass is by putting >> >> > @user.letters.should_receive(:find).with("1").and_return(@letter) >> >> > directly in the "should assign the found letter for the view" >> >> >> > I feel like I must be missing something about how stubbing and mocking >> >> > work >> >> >> > ?# Get /admin/letters/1 >> >> > ?def show >> >> > ? ?id = params[:id] >> >> > ? ?@letter = ?@user.letters.find(id) >> >> > ?end >> >> >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do >> >> >> > ?before(:each) do >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) >> >> >> This @user is an instance variable in the spec, and is not the same >> >> @user that is in the controller. >> >> >> HTH, >> >> David >> >> >> > ?end >> >> >> > ?def do_get >> >> > ? ?put :show, {:id => "1"}, @session >> >> > ?end >> >> >> > ?login_and_before_filter_pass(:filter => :admin_only, >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) >> >> >> > ?it "should be successful" do >> >> > ? ?do_get >> >> > ? ?response.should be_success >> >> > ?end >> >> >> > ?it "should find the letter requested" do >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) >> >> > ? ?puts(@letter) >> >> > ? ?do_get >> >> > ?end >> >> >> > ?it "should assign the found letter for the view" do >> >> > ? ?# uncommenting will allow to pass >> >> > ? ?# @user.letters.should_receive(:find).with("1").and_return >> >> > (@letter) >> >> > ? ?do_get >> >> > ? ?assigns[:letter].should equal(@letter) >> >> > ?end >> >> >> > ?it "should render show template" do >> >> > ? ?do_get >> >> > ? ?response.should render_template("show") >> >> > ?end >> >> >> > end >> >> >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: >> >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: >> >> >> > How do I spec this following example from the Agile Rails Book listed >> >> >> > below. I am doing a similar thing in my controller and when I >> >> >> > attempted to change it to the collection way of doing the find I am >> >> >> > unable to get my spec to pass though I know it is working fine as my >> >> >> > cucumber features are passing >> >> >> >> > old rails way: >> >> >> >> > def show >> >> >> > @order = Order.find(params[:id]) >> >> >> > end >> >> >> >> > new rails way collection-based: >> >> >> >> > def show >> >> >> > id = params[:id] >> >> >> > @order = @user.orders.find(id) >> >> >> >> This code is inherently untestable in an isolated/granular way. Your >> >> >> options are: >> >> >> >> * write higher level specs that use real data >> >> >> ? * pros: simplicity and clarity in both code and specs >> >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow >> >> >> >> * write a very invasive spec with complex setup and instance_eval to >> >> >> set up the @user >> >> >> ? * pros: runs fast, no runtime dependency on correct models >> >> >> ? * cons: brittle due to dependency on internals, complex >> >> >> >> * refactor the code to make it easier to spec >> >> >> ? * pros: more highly decoupled code, simpler specs, fast >> >> >> ? * cons: more work up front, may disregard some of what Rails has to offer >> >> >> >> Note that the first two options are both brittle, but for different >> >> >> reasons. The first is brittle due to a runtime dependency. That means >> >> >> that when you run the spec the model has to be working correctly for >> >> >> the spec to pass, and a failure could be due to a problem in the model >> >> >> or in the controller. >> >> >> >> The second is due to a code dependency. That means that when you want >> >> >> to change this code, the spec will have to change as well. This is >> >> >> true of any case in which you use mocks or stubs to varying degrees, >> >> >> and that comes with its own tradeoffs. In this case, the necessary >> >> >> stubbing would be complex and invasive enough that it would be a >> >> >> concern to me. >> >> >> >> Getting to your original question - what does your spec look like now, >> >> >> and what failure message are you getting? >> >> >> >> Cheers, >> >> >> David >> >> >> >> > rescue >> >> >> > redirect_to :action => "index" >> >> >> > end >> >> >> > _______________________________________________ >> >> >> > rspec-users mailing list >> >> >> > rspec-us... at rubyforge.org >> >> >> >http://rubyforge.org/mailman/listinfo/rspec-users >> >> >> >> _______________________________________________ >> >> >> rspec-users mailing list >> >> >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users >> >> > _______________________________________________ >> >> > rspec-users mailing list >> >> > rspec-us... at rubyforge.org >> >> >http://rubyforge.org/mailman/listinfo/rspec-users >> >> >> _______________________________________________ >> >> rspec-users mailing list >> >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users >> > _______________________________________________ >> > rspec-users mailing list >> > rspec-us... at rubyforge.org >> >http://rubyforge.org/mailman/listinfo/rspec-users >> >> _______________________________________________ >> rspec-users mailing list >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Here is the code, I pasted the letter_controller.rb, letters_controller_spec.rb and the controllers macros.rb, thanks again for your help. On Jul 22, 12:11?pm, David Chelimsky <dchelim... at gmail.com> wrote:> On Wed, Jul 22, 2009 at 10:52 AM, amkirwan<amkir... at gmail.com> wrote: > > Okay I get the "and_return" part now thanks. > > > Here is the error > > >http://gist.github.com/152061 > > Well, the error seems quite clear. It''s expecting a Letter and gets a Person. > > I know you''ve posted bits of the code in this thread, but would you > mind posting the entire spec and controller code in a gist? At least > the code related to the show action. > > Thanks, > David > > > > > > > > > On Jul 22, 11:39?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkir... at gmail.com> wrote: > >> > Thanks for the help but I guess I am not getting something. How is > >> > @user= = mock_model(Person) and different then the following code: > > >> This is assigning the mock_model(Person) to a @user instance variable > >> in the spec. This is not the same user that is in the controller. > > >> > message = mock_model(Message) > >> > Message.stub!(:new).and_return message > >> > message.should_receive(:save) > >> > post :create > > >> This creates a mock_model(Message) and then tells Message to return it > >> when it receives :new, therefore message in the spec is the same > >> object as Message.new in the controller. > > >> > def create > >> > message = Message.new params[:new] > >> > message.save > >> > end > >> > I guess I don''t understand why assigns[:letter] is expecting a Person > >> > instance instead of a Letter instance > > >> I''m not clear on what you mean by this. Would you please post the full > >> error message (either here or in a pastie or gist)? > > >> > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: > >> >> > My spec is a messed up because I have tried everything I can think of > >> >> > to mock but this is what I have for the show method. The @user > >> >> > instance is setup in the login_and_before_filter_pass macros with the > >> >> > following: @user = mock_model(Person, :null_object => true) > > >> >> > The error I keep receiving is that assigns[:letter].should equal > >> >> > @letter keeps return that it is expecting a Person object instead of a > >> >> > Letter object. The only way I can get it to pass is by putting > >> >> > @user.letters.should_receive(:find).with("1").and_return(@letter) > >> >> > directly in the "should assign the found letter for the view" > > >> >> > I feel like I must be missing something about how stubbing and mocking > >> >> > work > > >> >> > ?# Get /admin/letters/1 > >> >> > ?def show > >> >> > ? ?id = params[:id] > >> >> > ? ?@letter = ?@user.letters.find(id) > >> >> > ?end > > >> >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do > > >> >> > ?before(:each) do > >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > > >> >> This @user is an instance variable in the spec, and is not the same > >> >> @user that is in the controller. > > >> >> HTH, > >> >> David > > >> >> > ?end > > >> >> > ?def do_get > >> >> > ? ?put :show, {:id => "1"}, @session > >> >> > ?end > > >> >> > ?login_and_before_filter_pass(:filter => :admin_only, > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) > > >> >> > ?it "should be successful" do > >> >> > ? ?do_get > >> >> > ? ?response.should be_success > >> >> > ?end > > >> >> > ?it "should find the letter requested" do > >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > >> >> > ? ?puts(@letter) > >> >> > ? ?do_get > >> >> > ?end > > >> >> > ?it "should assign the found letter for the view" do > >> >> > ? ?# uncommenting will allow to pass > >> >> > ? ?# @user.letters.should_receive(:find).with("1").and_return > >> >> > (@letter) > >> >> > ? ?do_get > >> >> > ? ?assigns[:letter].should equal(@letter) > >> >> > ?end > > >> >> > ?it "should render show template" do > >> >> > ? ?do_get > >> >> > ? ?response.should render_template("show") > >> >> > ?end > > >> >> > end > > >> >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: > >> >> >> > How do I spec this following example from the Agile Rails Book listed > >> >> >> > below. I am doing a similar thing in my controller and when I > >> >> >> > attempted to change it to the collection way of doing the find I am > >> >> >> > unable to get my spec to pass though I know it is working fine as my > >> >> >> > cucumber features are passing > > >> >> >> > old rails way: > > >> >> >> > def show > >> >> >> > @order = Order.find(params[:id]) > >> >> >> > end > > >> >> >> > new rails way collection-based: > > >> >> >> > def show > >> >> >> > id = params[:id] > >> >> >> > @order = @user.orders.find(id) > > >> >> >> This code is inherently untestable in an isolated/granular way. Your > >> >> >> options are: > > >> >> >> * write higher level specs that use real data > >> >> >> ? * pros: simplicity and clarity in both code and specs > >> >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow > > >> >> >> * write a very invasive spec with complex setup and instance_eval to > >> >> >> set up the @user > >> >> >> ? * pros: runs fast, no runtime dependency on correct models > >> >> >> ? * cons: brittle due to dependency on internals, complex > > >> >> >> * refactor the code to make it easier to spec > >> >> >> ? * pros: more highly decoupled code, simpler specs, fast > >> >> >> ? * cons: more work up front, may disregard some of what Rails has to offer > > >> >> >> Note that the first two options are both brittle, but for different > >> >> >> reasons. The first is brittle due to a runtime dependency. That means > >> >> >> that when you run the spec the model has to be working correctly for > >> >> >> the spec to pass, and a failure could be due to a problem in the model > >> >> >> or in the controller. > > >> >> >> The second is due to a code dependency. That means that when you want > >> >> >> to change this code, the spec will have to change as well. This is > >> >> >> true of any case in which you use mocks or stubs to varying degrees, > >> >> >> and that comes with its own tradeoffs. In this case, the necessary > >> >> >> stubbing would be complex and invasive enough that it would be a > >> >> >> concern to me. > > >> >> >> Getting to your original question - what does your spec look like now, > >> >> >> and what failure message are you getting? > > >> >> >> Cheers, > >> >> >> David > > >> >> >> > rescue > >> >> >> > redirect_to :action => "index" > >> >> >> > end > >> >> >> > _______________________________________________ > >> >> >> > rspec-users mailing list > >> >> >> > rspec-us... at rubyforge.org > >> >> >> >http://rubyforge.org/mailman/listinfo/rspec-users > > >> >> >> _______________________________________________ > >> >> >> rspec-users mailing list > >> >> >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > >> >> > _______________________________________________ > >> >> > rspec-users mailing list > >> >> > rspec-us... at rubyforge.org > >> >> >http://rubyforge.org/mailman/listinfo/rspec-users > > >> >> _______________________________________________ > >> >> rspec-users mailing list > >> >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > >> > _______________________________________________ > >> > rspec-users mailing list > >> > rspec-us... at rubyforge.org > >> >http://rubyforge.org/mailman/listinfo/rspec-users > > >> _______________________________________________ > >> rspec-users mailing list > >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > > rspec-users mailing list > > rspec-us... at rubyforge.org > >http://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
On Wed, Jul 22, 2009 at 11:38 AM, amkirwan<amkirwan at gmail.com> wrote:> Here is the code,Where? I don''t see code pasted or a link to a gist.> I pasted the letter_controller.rb, > letters_controller_spec.rb and the controllers macros.rb, thanks again > for your help. > > On Jul 22, 12:11?pm, David Chelimsky <dchelim... at gmail.com> wrote: >> On Wed, Jul 22, 2009 at 10:52 AM, amkirwan<amkir... at gmail.com> wrote: >> > Okay I get the "and_return" part now thanks. >> >> > Here is the error >> >> >http://gist.github.com/152061 >> >> Well, the error seems quite clear. It''s expecting a Letter and gets a Person. >> >> I know you''ve posted bits of the code in this thread, but would you >> mind posting the entire spec and controller code in a gist? At least >> the code related to the show action. >> >> Thanks, >> David >> >> >> >> >> >> >> >> > On Jul 22, 11:39?am, David Chelimsky <dchelim... at gmail.com> wrote: >> >> On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkir... at gmail.com> wrote: >> >> > Thanks for the help but I guess I am not getting something. How is >> >> > @user= = mock_model(Person) and different then the following code: >> >> >> This is assigning the mock_model(Person) to a @user instance variable >> >> in the spec. This is not the same user that is in the controller. >> >> >> > message = mock_model(Message) >> >> > Message.stub!(:new).and_return message >> >> > message.should_receive(:save) >> >> > post :create >> >> >> This creates a mock_model(Message) and then tells Message to return it >> >> when it receives :new, therefore message in the spec is the same >> >> object as Message.new in the controller. >> >> >> > def create >> >> > message = Message.new params[:new] >> >> > message.save >> >> > end >> >> > I guess I don''t understand why assigns[:letter] is expecting a Person >> >> > instance instead of a Letter instance >> >> >> I''m not clear on what you mean by this. Would you please post the full >> >> error message (either here or in a pastie or gist)? >> >> >> > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: >> >> >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: >> >> >> > My spec is a messed up because I have tried everything I can think of >> >> >> > to mock but this is what I have for the show method. The @user >> >> >> > instance is setup in the login_and_before_filter_pass macros with the >> >> >> > following: @user = mock_model(Person, :null_object => true) >> >> >> >> > The error I keep receiving is that assigns[:letter].should equal >> >> >> > @letter keeps return that it is expecting a Person object instead of a >> >> >> > Letter object. The only way I can get it to pass is by putting >> >> >> > @user.letters.should_receive(:find).with("1").and_return(@letter) >> >> >> > directly in the "should assign the found letter for the view" >> >> >> >> > I feel like I must be missing something about how stubbing and mocking >> >> >> > work >> >> >> >> > ?# Get /admin/letters/1 >> >> >> > ?def show >> >> >> > ? ?id = params[:id] >> >> >> > ? ?@letter = ?@user.letters.find(id) >> >> >> > ?end >> >> >> >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do >> >> >> >> > ?before(:each) do >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) >> >> >> >> This @user is an instance variable in the spec, and is not the same >> >> >> @user that is in the controller. >> >> >> >> HTH, >> >> >> David >> >> >> >> > ?end >> >> >> >> > ?def do_get >> >> >> > ? ?put :show, {:id => "1"}, @session >> >> >> > ?end >> >> >> >> > ?login_and_before_filter_pass(:filter => :admin_only, >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) >> >> >> >> > ?it "should be successful" do >> >> >> > ? ?do_get >> >> >> > ? ?response.should be_success >> >> >> > ?end >> >> >> >> > ?it "should find the letter requested" do >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) >> >> >> > ? ?puts(@letter) >> >> >> > ? ?do_get >> >> >> > ?end >> >> >> >> > ?it "should assign the found letter for the view" do >> >> >> > ? ?# uncommenting will allow to pass >> >> >> > ? ?# @user.letters.should_receive(:find).with("1").and_return >> >> >> > (@letter) >> >> >> > ? ?do_get >> >> >> > ? ?assigns[:letter].should equal(@letter) >> >> >> > ?end >> >> >> >> > ?it "should render show template" do >> >> >> > ? ?do_get >> >> >> > ? ?response.should render_template("show") >> >> >> > ?end >> >> >> >> > end >> >> >> >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: >> >> >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: >> >> >> >> > How do I spec this following example from the Agile Rails Book listed >> >> >> >> > below. I am doing a similar thing in my controller and when I >> >> >> >> > attempted to change it to the collection way of doing the find I am >> >> >> >> > unable to get my spec to pass though I know it is working fine as my >> >> >> >> > cucumber features are passing >> >> >> >> >> > old rails way: >> >> >> >> >> > def show >> >> >> >> > @order = Order.find(params[:id]) >> >> >> >> > end >> >> >> >> >> > new rails way collection-based: >> >> >> >> >> > def show >> >> >> >> > id = params[:id] >> >> >> >> > @order = @user.orders.find(id) >> >> >> >> >> This code is inherently untestable in an isolated/granular way. Your >> >> >> >> options are: >> >> >> >> >> * write higher level specs that use real data >> >> >> >> ? * pros: simplicity and clarity in both code and specs >> >> >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow >> >> >> >> >> * write a very invasive spec with complex setup and instance_eval to >> >> >> >> set up the @user >> >> >> >> ? * pros: runs fast, no runtime dependency on correct models >> >> >> >> ? * cons: brittle due to dependency on internals, complex >> >> >> >> >> * refactor the code to make it easier to spec >> >> >> >> ? * pros: more highly decoupled code, simpler specs, fast >> >> >> >> ? * cons: more work up front, may disregard some of what Rails has to offer >> >> >> >> >> Note that the first two options are both brittle, but for different >> >> >> >> reasons. The first is brittle due to a runtime dependency. That means >> >> >> >> that when you run the spec the model has to be working correctly for >> >> >> >> the spec to pass, and a failure could be due to a problem in the model >> >> >> >> or in the controller. >> >> >> >> >> The second is due to a code dependency. That means that when you want >> >> >> >> to change this code, the spec will have to change as well. This is >> >> >> >> true of any case in which you use mocks or stubs to varying degrees, >> >> >> >> and that comes with its own tradeoffs. In this case, the necessary >> >> >> >> stubbing would be complex and invasive enough that it would be a >> >> >> >> concern to me. >> >> >> >> >> Getting to your original question - what does your spec look like now, >> >> >> >> and what failure message are you getting? >> >> >> >> >> Cheers, >> >> >> >> David >> >> >> >> >> > rescue >> >> >> >> > redirect_to :action => "index" >> >> >> >> > end
sorry here it is http://gist.github.com/152123 On Jul 22, 1:02?pm, David Chelimsky <dchelim... at gmail.com> wrote:> On Wed, Jul 22, 2009 at 11:38 AM, amkirwan<amkir... at gmail.com> wrote: > > Here is the code, > > Where? I don''t see code pasted or a link to a gist. > > > > > > > I pasted the letter_controller.rb, > > letters_controller_spec.rb and the controllers macros.rb, thanks again > > for your help. > > > On Jul 22, 12:11?pm, David Chelimsky <dchelim... at gmail.com> wrote: > >> On Wed, Jul 22, 2009 at 10:52 AM, amkirwan<amkir... at gmail.com> wrote: > >> > Okay I get the "and_return" part now thanks. > > >> > Here is the error > > >> >http://gist.github.com/152061 > > >> Well, the error seems quite clear. It''s expecting a Letter and gets a Person. > > >> I know you''ve posted bits of the code in this thread, but would you > >> mind posting the entire spec and controller code in a gist? At least > >> the code related to the show action. > > >> Thanks, > >> David > > >> > On Jul 22, 11:39?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkir... at gmail.com> wrote: > >> >> > Thanks for the help but I guess I am not getting something. How is > >> >> > @user= = mock_model(Person) and different then the following code: > > >> >> This is assigning the mock_model(Person) to a @user instance variable > >> >> in the spec. This is not the same user that is in the controller. > > >> >> > message = mock_model(Message) > >> >> > Message.stub!(:new).and_return message > >> >> > message.should_receive(:save) > >> >> > post :create > > >> >> This creates a mock_model(Message) and then tells Message to return it > >> >> when it receives :new, therefore message in the spec is the same > >> >> object as Message.new in the controller. > > >> >> > def create > >> >> > message = Message.new params[:new] > >> >> > message.save > >> >> > end > >> >> > I guess I don''t understand why assigns[:letter] is expecting a Person > >> >> > instance instead of a Letter instance > > >> >> I''m not clear on what you mean by this. Would you please post the full > >> >> error message (either here or in a pastie or gist)? > > >> >> > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: > >> >> >> > My spec is a messed up because I have tried everything I can think of > >> >> >> > to mock but this is what I have for the show method. The @user > >> >> >> > instance is setup in the login_and_before_filter_pass macros with the > >> >> >> > following: @user = mock_model(Person, :null_object => true) > > >> >> >> > The error I keep receiving is that assigns[:letter].should equal > >> >> >> > @letter keeps return that it is expecting a Person object instead of a > >> >> >> > Letter object. The only way I can get it to pass is by putting > >> >> >> > @user.letters.should_receive(:find).with("1").and_return(@letter) > >> >> >> > directly in the "should assign the found letter for the view" > > >> >> >> > I feel like I must be missing something about how stubbing and mocking > >> >> >> > work > > >> >> >> > ?# Get /admin/letters/1 > >> >> >> > ?def show > >> >> >> > ? ?id = params[:id] > >> >> >> > ? ?@letter = ?@user.letters.find(id) > >> >> >> > ?end > > >> >> >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do > > >> >> >> > ?before(:each) do > >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > > >> >> >> This @user is an instance variable in the spec, and is not the same > >> >> >> @user that is in the controller. > > >> >> >> HTH, > >> >> >> David > > >> >> >> > ?end > > >> >> >> > ?def do_get > >> >> >> > ? ?put :show, {:id => "1"}, @session > >> >> >> > ?end > > >> >> >> > ?login_and_before_filter_pass(:filter => :admin_only, > >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, > >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, > >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) > > >> >> >> > ?it "should be successful" do > >> >> >> > ? ?do_get > >> >> >> > ? ?response.should be_success > >> >> >> > ?end > > >> >> >> > ?it "should find the letter requested" do > >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > >> >> >> > ? ?puts(@letter) > >> >> >> > ? ?do_get > >> >> >> > ?end > > >> >> >> > ?it "should assign the found letter for the view" do > >> >> >> > ? ?# uncommenting will allow to pass > >> >> >> > ? ?# @user.letters.should_receive(:find).with("1").and_return > >> >> >> > (@letter) > >> >> >> > ? ?do_get > >> >> >> > ? ?assigns[:letter].should equal(@letter) > >> >> >> > ?end > > >> >> >> > ?it "should render show template" do > >> >> >> > ? ?do_get > >> >> >> > ? ?response.should render_template("show") > >> >> >> > ?end > > >> >> >> > end > > >> >> >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: > >> >> >> >> > How do I spec this following example from the Agile Rails Book listed > >> >> >> >> > below. I am doing a similar thing in my controller and when I > >> >> >> >> > attempted to change it to the collection way of doing the find I am > >> >> >> >> > unable to get my spec to pass though I know it is working fine as my > >> >> >> >> > cucumber features are passing > > >> >> >> >> > old rails way: > > >> >> >> >> > def show > >> >> >> >> > @order = Order.find(params[:id]) > >> >> >> >> > end > > >> >> >> >> > new rails way collection-based: > > >> >> >> >> > def show > >> >> >> >> > id = params[:id] > >> >> >> >> > @order = @user.orders.find(id) > > >> >> >> >> This code is inherently untestable in an isolated/granular way. Your > >> >> >> >> options are: > > >> >> >> >> * write higher level specs that use real data > >> >> >> >> ? * pros: simplicity and clarity in both code and specs > >> >> >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow > > >> >> >> >> * write a very invasive spec with complex setup and instance_eval to > >> >> >> >> set up the @user > >> >> >> >> ? * pros: runs fast, no runtime dependency on correct models > >> >> >> >> ? * cons: brittle due to dependency on internals, complex > > >> >> >> >> * refactor the code to make it easier to spec > >> >> >> >> ? * pros: more highly decoupled code, simpler specs, fast > >> >> >> >> ? * cons: more work up front, may disregard some of what Rails has to offer > > >> >> >> >> Note that the first two options are both brittle, but for different > >> >> >> >> reasons. The first is brittle due to a runtime dependency. That means > >> >> >> >> that when you run the spec the model has to be working correctly for > >> >> >> >> the spec to pass, and a failure could be due to a problem in the model > >> >> >> >> or in the controller. > > >> >> >> >> The second is due to a code dependency. That means that when you want > >> >> >> >> to change this code, the spec will have to change as well. This is > >> >> >> >> true of any case in which you use mocks or stubs to varying degrees, > >> >> >> >> and that comes with its own tradeoffs. In this case, the necessary > >> >> >> >> stubbing would be complex and invasive enough that it would be a > >> >> >> >> concern to me. > > >> >> >> >> Getting to your original question - what does your spec look like now, > >> >> >> >> and what failure message are you getting? > > >> >> >> >> Cheers, > >> >> >> >> David > > >> >> >> >> > rescue > >> >> >> >> > redirect_to :action => "index" > >> >> >> >> > end > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
I have also posted the original passing spec and controller before I tried to change the find to @user.letters.find(id) http://gist.github.com/152175 On Jul 22, 1:33?pm, amkirwan <amkir... at gmail.com> wrote:> sorry here it ishttp://gist.github.com/152123 > > On Jul 22, 1:02?pm, David Chelimsky <dchelim... at gmail.com> wrote: > > > > > On Wed, Jul 22, 2009 at 11:38 AM, amkirwan<amkir... at gmail.com> wrote: > > > Here is the code, > > > Where? I don''t see code pasted or a link to a gist. > > > > I pasted the letter_controller.rb, > > > letters_controller_spec.rb and the controllers macros.rb, thanks again > > > for your help. > > > > On Jul 22, 12:11?pm, David Chelimsky <dchelim... at gmail.com> wrote: > > >> On Wed, Jul 22, 2009 at 10:52 AM, amkirwan<amkir... at gmail.com> wrote: > > >> > Okay I get the "and_return" part now thanks. > > > >> > Here is the error > > > >> >http://gist.github.com/152061 > > > >> Well, the error seems quite clear. It''s expecting a Letter and gets a Person. > > > >> I know you''ve posted bits of the code in this thread, but would you > > >> mind posting the entire spec and controller code in a gist? At least > > >> the code related to the show action. > > > >> Thanks, > > >> David > > > >> > On Jul 22, 11:39?am, David Chelimsky <dchelim... at gmail.com> wrote: > > >> >> On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkir... at gmail.com> wrote: > > >> >> > Thanks for the help but I guess I am not getting something. How is > > >> >> > @user= = mock_model(Person) and different then the following code: > > > >> >> This is assigning the mock_model(Person) to a @user instance variable > > >> >> in the spec. This is not the same user that is in the controller. > > > >> >> > message = mock_model(Message) > > >> >> > Message.stub!(:new).and_return message > > >> >> > message.should_receive(:save) > > >> >> > post :create > > > >> >> This creates a mock_model(Message) and then tells Message to return it > > >> >> when it receives :new, therefore message in the spec is the same > > >> >> object as Message.new in the controller. > > > >> >> > def create > > >> >> > message = Message.new params[:new] > > >> >> > message.save > > >> >> > end > > >> >> > I guess I don''t understand why assigns[:letter] is expecting a Person > > >> >> > instance instead of a Letter instance > > > >> >> I''m not clear on what you mean by this. Would you please post the full > > >> >> error message (either here or in a pastie or gist)? > > > >> >> > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: > > >> >> >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: > > >> >> >> > My spec is a messed up because I have tried everything I can think of > > >> >> >> > to mock but this is what I have for the show method. The @user > > >> >> >> > instance is setup in the login_and_before_filter_pass macros with the > > >> >> >> > following: @user = mock_model(Person, :null_object => true) > > > >> >> >> > The error I keep receiving is that assigns[:letter].should equal > > >> >> >> > @letter keeps return that it is expecting a Person object instead of a > > >> >> >> > Letter object. The only way I can get it to pass is by putting > > >> >> >> > @user.letters.should_receive(:find).with("1").and_return(@letter) > > >> >> >> > directly in the "should assign the found letter for the view" > > > >> >> >> > I feel like I must be missing something about how stubbing and mocking > > >> >> >> > work > > > >> >> >> > ?# Get /admin/letters/1 > > >> >> >> > ?def show > > >> >> >> > ? ?id = params[:id] > > >> >> >> > ? ?@letter = ?@user.letters.find(id) > > >> >> >> > ?end > > > >> >> >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do > > > >> >> >> > ?before(:each) do > > >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > > > >> >> >> This @user is an instance variable in the spec, and is not the same > > >> >> >> @user that is in the controller. > > > >> >> >> HTH, > > >> >> >> David > > > >> >> >> > ?end > > > >> >> >> > ?def do_get > > >> >> >> > ? ?put :show, {:id => "1"}, @session > > >> >> >> > ?end > > > >> >> >> > ?login_and_before_filter_pass(:filter => :admin_only, > > >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, > > >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, > > >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) > > > >> >> >> > ?it "should be successful" do > > >> >> >> > ? ?do_get > > >> >> >> > ? ?response.should be_success > > >> >> >> > ?end > > > >> >> >> > ?it "should find the letter requested" do > > >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > > >> >> >> > ? ?puts(@letter) > > >> >> >> > ? ?do_get > > >> >> >> > ?end > > > >> >> >> > ?it "should assign the found letter for the view" do > > >> >> >> > ? ?# uncommenting will allow to pass > > >> >> >> > ? ?# @user.letters.should_receive(:find).with("1").and_return > > >> >> >> > (@letter) > > >> >> >> > ? ?do_get > > >> >> >> > ? ?assigns[:letter].should equal(@letter) > > >> >> >> > ?end > > > >> >> >> > ?it "should render show template" do > > >> >> >> > ? ?do_get > > >> >> >> > ? ?response.should render_template("show") > > >> >> >> > ?end > > > >> >> >> > end > > > >> >> >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: > > >> >> >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: > > >> >> >> >> > How do I spec this following example from the Agile Rails Book listed > > >> >> >> >> > below. I am doing a similar thing in my controller and when I > > >> >> >> >> > attempted to change it to the collection way of doing the find I am > > >> >> >> >> > unable to get my spec to pass though I know it is working fine as my > > >> >> >> >> > cucumber features are passing > > > >> >> >> >> > old rails way: > > > >> >> >> >> > def show > > >> >> >> >> > @order = Order.find(params[:id]) > > >> >> >> >> > end > > > >> >> >> >> > new rails way collection-based: > > > >> >> >> >> > def show > > >> >> >> >> > id = params[:id] > > >> >> >> >> > @order = @user.orders.find(id) > > > >> >> >> >> This code is inherently untestable in an isolated/granular way. Your > > >> >> >> >> options are: > > > >> >> >> >> * write higher level specs that use real data > > >> >> >> >> ? * pros: simplicity and clarity in both code and specs > > >> >> >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow > > > >> >> >> >> * write a very invasive spec with complex setup and instance_eval to > > >> >> >> >> set up the @user > > >> >> >> >> ? * pros: runs fast, no runtime dependency on correct models > > >> >> >> >> ? * cons: brittle due to dependency on internals, complex > > > >> >> >> >> * refactor the code to make it easier to spec > > >> >> >> >> ? * pros: more highly decoupled code, simpler specs, fast > > >> >> >> >> ? * cons: more work up front, may disregard some of what Rails has to offer > > > >> >> >> >> Note that the first two options are both brittle, but for different > > >> >> >> >> reasons. The first is brittle due to a runtime dependency. That means > > >> >> >> >> that when you run the spec the model has to be working correctly for > > >> >> >> >> the spec to pass, and a failure could be due to a problem in the model > > >> >> >> >> or in the controller. > > > >> >> >> >> The second is due to a code dependency. That means that when you want > > >> >> >> >> to change this code, the spec will have to change as well. This is > > >> >> >> >> true of any case in which you use mocks or stubs to varying degrees, > > >> >> >> >> and that comes with its own tradeoffs. In this case, the necessary > > >> >> >> >> stubbing would be complex and invasive enough that it would be a > > >> >> >> >> concern to me. > > > >> >> >> >> Getting to your original question - what does your spec look like now, > > >> >> >> >> and what failure message are you getting? > > > >> >> >> >> Cheers, > > >> >> >> >> David > > > >> >> >> >> > rescue > > >> >> >> >> > redirect_to :action => "index" > > >> >> >> >> > end > > > _______________________________________________ > > rspec-users mailing list > > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
On Wed, Jul 22, 2009 at 12:33 PM, amkirwan<amkirwan at gmail.com> wrote:> sorry here it is > http://gist.github.com/152123I see find_by_partners_uid referenced in the login_and_before_filter_pass macro and again in before(:each) - so there is likely some conflict there. Also, I don''t see where find_by_partners_uid is ever called in the controller.> > On Jul 22, 1:02?pm, David Chelimsky <dchelim... at gmail.com> wrote: >> On Wed, Jul 22, 2009 at 11:38 AM, amkirwan<amkir... at gmail.com> wrote: >> > Here is the code, >> >> Where? I don''t see code pasted or a link to a gist. >> >> >> >> >> >> > I pasted the letter_controller.rb, >> > letters_controller_spec.rb and the controllers macros.rb, thanks again >> > for your help. >> >> > On Jul 22, 12:11?pm, David Chelimsky <dchelim... at gmail.com> wrote: >> >> On Wed, Jul 22, 2009 at 10:52 AM, amkirwan<amkir... at gmail.com> wrote: >> >> > Okay I get the "and_return" part now thanks. >> >> >> > Here is the error >> >> >> >http://gist.github.com/152061 >> >> >> Well, the error seems quite clear. It''s expecting a Letter and gets a Person. >> >> >> I know you''ve posted bits of the code in this thread, but would you >> >> mind posting the entire spec and controller code in a gist? At least >> >> the code related to the show action. >> >> >> Thanks, >> >> David >> >> >> > On Jul 22, 11:39?am, David Chelimsky <dchelim... at gmail.com> wrote: >> >> >> On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkir... at gmail.com> wrote: >> >> >> > Thanks for the help but I guess I am not getting something. How is >> >> >> > @user= = mock_model(Person) and different then the following code: >> >> >> >> This is assigning the mock_model(Person) to a @user instance variable >> >> >> in the spec. This is not the same user that is in the controller. >> >> >> >> > message = mock_model(Message) >> >> >> > Message.stub!(:new).and_return message >> >> >> > message.should_receive(:save) >> >> >> > post :create >> >> >> >> This creates a mock_model(Message) and then tells Message to return it >> >> >> when it receives :new, therefore message in the spec is the same >> >> >> object as Message.new in the controller. >> >> >> >> > def create >> >> >> > message = Message.new params[:new] >> >> >> > message.save >> >> >> > end >> >> >> > I guess I don''t understand why assigns[:letter] is expecting a Person >> >> >> > instance instead of a Letter instance >> >> >> >> I''m not clear on what you mean by this. Would you please post the full >> >> >> error message (either here or in a pastie or gist)? >> >> >> >> > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: >> >> >> >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: >> >> >> >> > My spec is a messed up because I have tried everything I can think of >> >> >> >> > to mock but this is what I have for the show method. The @user >> >> >> >> > instance is setup in the login_and_before_filter_pass macros with the >> >> >> >> > following: @user = mock_model(Person, :null_object => true) >> >> >> >> >> > The error I keep receiving is that assigns[:letter].should equal >> >> >> >> > @letter keeps return that it is expecting a Person object instead of a >> >> >> >> > Letter object. The only way I can get it to pass is by putting >> >> >> >> > @user.letters.should_receive(:find).with("1").and_return(@letter) >> >> >> >> > directly in the "should assign the found letter for the view" >> >> >> >> >> > I feel like I must be missing something about how stubbing and mocking >> >> >> >> > work >> >> >> >> >> > ?# Get /admin/letters/1 >> >> >> >> > ?def show >> >> >> >> > ? ?id = params[:id] >> >> >> >> > ? ?@letter = ?@user.letters.find(id) >> >> >> >> > ?end >> >> >> >> >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do >> >> >> >> >> > ?before(:each) do >> >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) >> >> >> >> >> This @user is an instance variable in the spec, and is not the same >> >> >> >> @user that is in the controller. >> >> >> >> >> HTH, >> >> >> >> David >> >> >> >> >> > ?end >> >> >> >> >> > ?def do_get >> >> >> >> > ? ?put :show, {:id => "1"}, @session >> >> >> >> > ?end >> >> >> >> >> > ?login_and_before_filter_pass(:filter => :admin_only, >> >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, >> >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, >> >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) >> >> >> >> >> > ?it "should be successful" do >> >> >> >> > ? ?do_get >> >> >> >> > ? ?response.should be_success >> >> >> >> > ?end >> >> >> >> >> > ?it "should find the letter requested" do >> >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) >> >> >> >> > ? ?puts(@letter) >> >> >> >> > ? ?do_get >> >> >> >> > ?end >> >> >> >> >> > ?it "should assign the found letter for the view" do >> >> >> >> > ? ?# uncommenting will allow to pass >> >> >> >> > ? ?# @user.letters.should_receive(:find).with("1").and_return >> >> >> >> > (@letter) >> >> >> >> > ? ?do_get >> >> >> >> > ? ?assigns[:letter].should equal(@letter) >> >> >> >> > ?end >> >> >> >> >> > ?it "should render show template" do >> >> >> >> > ? ?do_get >> >> >> >> > ? ?response.should render_template("show") >> >> >> >> > ?end >> >> >> >> >> > end >> >> >> >> >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: >> >> >> >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: >> >> >> >> >> > How do I spec this following example from the Agile Rails Book listed >> >> >> >> >> > below. I am doing a similar thing in my controller and when I >> >> >> >> >> > attempted to change it to the collection way of doing the find I am >> >> >> >> >> > unable to get my spec to pass though I know it is working fine as my >> >> >> >> >> > cucumber features are passing >> >> >> >> >> >> > old rails way: >> >> >> >> >> >> > def show >> >> >> >> >> > @order = Order.find(params[:id]) >> >> >> >> >> > end >> >> >> >> >> >> > new rails way collection-based: >> >> >> >> >> >> > def show >> >> >> >> >> > id = params[:id] >> >> >> >> >> > @order = @user.orders.find(id) >> >> >> >> >> >> This code is inherently untestable in an isolated/granular way. Your >> >> >> >> >> options are: >> >> >> >> >> >> * write higher level specs that use real data >> >> >> >> >> ? * pros: simplicity and clarity in both code and specs >> >> >> >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow >> >> >> >> >> >> * write a very invasive spec with complex setup and instance_eval to >> >> >> >> >> set up the @user >> >> >> >> >> ? * pros: runs fast, no runtime dependency on correct models >> >> >> >> >> ? * cons: brittle due to dependency on internals, complex >> >> >> >> >> >> * refactor the code to make it easier to spec >> >> >> >> >> ? * pros: more highly decoupled code, simpler specs, fast >> >> >> >> >> ? * cons: more work up front, may disregard some of what Rails has to offer >> >> >> >> >> >> Note that the first two options are both brittle, but for different >> >> >> >> >> reasons. The first is brittle due to a runtime dependency. That means >> >> >> >> >> that when you run the spec the model has to be working correctly for >> >> >> >> >> the spec to pass, and a failure could be due to a problem in the model >> >> >> >> >> or in the controller. >> >> >> >> >> >> The second is due to a code dependency. That means that when you want >> >> >> >> >> to change this code, the spec will have to change as well. This is >> >> >> >> >> true of any case in which you use mocks or stubs to varying degrees, >> >> >> >> >> and that comes with its own tradeoffs. In this case, the necessary >> >> >> >> >> stubbing would be complex and invasive enough that it would be a >> >> >> >> >> concern to me. >> >> >> >> >> >> Getting to your original question - what does your spec look like now, >> >> >> >> >> and what failure message are you getting? >> >> >> >> >> >> Cheers, >> >> >> >> >> David >> >> >> >> >> >> > rescue >> >> >> >> >> > redirect_to :action => "index" >> >> >> >> >> > end >> >> _______________________________________________ >> rspec-users mailing list >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
the find_by_partners_uid is in the ApplicationController before_filter which handles setting the @user via RubyCAS I removed some of the duplication since posting. Just some left over code from when I was trying everything earlier to get this to pass. I thought it would be easy but didn''t realize how difficult this step would be. I changed the following in macros to: def login_and_before_filter_pass(options) before(:each) do @user = mock_model(Person, :roles => true, :letters => true) @user.stub_chain(:roles, :find_by_name => true) Person.stub!(:find_by_partners_uid).once.and_return(@user) end That gets me closer I think but I receive a: should assign @user undefined method `find'' for true:TrueClass which makes sense, just not sure where to go from here. On Jul 22, 2:33?pm, David Chelimsky <dchelim... at gmail.com> wrote:> On Wed, Jul 22, 2009 at 12:33 PM, amkirwan<amkir... at gmail.com> wrote: > > sorry here it is > >http://gist.github.com/152123 > > I see find_by_partners_uid referenced in the > login_and_before_filter_pass macro and again in before(:each) - so > there is likely some conflict there. Also, I don''t see where > find_by_partners_uid is ever called in the controller. > > > > > > > > > On Jul 22, 1:02?pm, David Chelimsky <dchelim... at gmail.com> wrote: > >> On Wed, Jul 22, 2009 at 11:38 AM, amkirwan<amkir... at gmail.com> wrote: > >> > Here is the code, > > >> Where? I don''t see code pasted or a link to a gist. > > >> > I pasted the letter_controller.rb, > >> > letters_controller_spec.rb and the controllers macros.rb, thanks again > >> > for your help. > > >> > On Jul 22, 12:11?pm, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> On Wed, Jul 22, 2009 at 10:52 AM, amkirwan<amkir... at gmail.com> wrote: > >> >> > Okay I get the "and_return" part now thanks. > > >> >> > Here is the error > > >> >> >http://gist.github.com/152061 > > >> >> Well, the error seems quite clear. It''s expecting a Letter and gets a Person. > > >> >> I know you''ve posted bits of the code in this thread, but would you > >> >> mind posting the entire spec and controller code in a gist? At least > >> >> the code related to the show action. > > >> >> Thanks, > >> >> David > > >> >> > On Jul 22, 11:39?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> >> On Wed, Jul 22, 2009 at 10:31 AM, amkirwan<amkir... at gmail.com> wrote: > >> >> >> > Thanks for the help but I guess I am not getting something. How is > >> >> >> > @user= = mock_model(Person) and different then the following code: > > >> >> >> This is assigning the mock_model(Person) to a @user instance variable > >> >> >> in the spec. This is not the same user that is in the controller. > > >> >> >> > message = mock_model(Message) > >> >> >> > Message.stub!(:new).and_return message > >> >> >> > message.should_receive(:save) > >> >> >> > post :create > > >> >> >> This creates a mock_model(Message) and then tells Message to return it > >> >> >> when it receives :new, therefore message in the spec is the same > >> >> >> object as Message.new in the controller. > > >> >> >> > def create > >> >> >> > message = Message.new params[:new] > >> >> >> > message.save > >> >> >> > end > >> >> >> > I guess I don''t understand why assigns[:letter] is expecting a Person > >> >> >> > instance instead of a Letter instance > > >> >> >> I''m not clear on what you mean by this. Would you please post the full > >> >> >> error message (either here or in a pastie or gist)? > > >> >> >> > On Jul 22, 10:42?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> >> >> On Wed, Jul 22, 2009 at 9:12 AM, amkirwan<amkir... at gmail.com> wrote: > >> >> >> >> > My spec is a messed up because I have tried everything I can think of > >> >> >> >> > to mock but this is what I have for the show method. The @user > >> >> >> >> > instance is setup in the login_and_before_filter_pass macros with the > >> >> >> >> > following: @user = mock_model(Person, :null_object => true) > > >> >> >> >> > The error I keep receiving is that assigns[:letter].should equal > >> >> >> >> > @letter keeps return that it is expecting a Person object instead of a > >> >> >> >> > Letter object. The only way I can get it to pass is by putting > >> >> >> >> > @user.letters.should_receive(:find).with("1").and_return(@letter) > >> >> >> >> > directly in the "should assign the found letter for the view" > > >> >> >> >> > I feel like I must be missing something about how stubbing and mocking > >> >> >> >> > work > > >> >> >> >> > ?# Get /admin/letters/1 > >> >> >> >> > ?def show > >> >> >> >> > ? ?id = params[:id] > >> >> >> >> > ? ?@letter = ?@user.letters.find(id) > >> >> >> >> > ?end > > >> >> >> >> > describe Admin::LettersController, "SHOW GET /admin/letters/1" do > > >> >> >> >> > ?before(:each) do > >> >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > > >> >> >> >> This @user is an instance variable in the spec, and is not the same > >> >> >> >> @user that is in the controller. > > >> >> >> >> HTH, > >> >> >> >> David > > >> >> >> >> > ?end > > >> >> >> >> > ?def do_get > >> >> >> >> > ? ?put :show, {:id => "1"}, @session > >> >> >> >> > ?end > > >> >> >> >> > ?login_and_before_filter_pass(:filter => :admin_only, > >> >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :request_method => :get, > >> >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :action => :show, > >> >> >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? :parameters => {:cas_user => ''ak730''}) > > >> >> >> >> > ?it "should be successful" do > >> >> >> >> > ? ?do_get > >> >> >> >> > ? ?response.should be_success > >> >> >> >> > ?end > > >> >> >> >> > ?it "should find the letter requested" do > >> >> >> >> > ? ?@user.letters.should_receive(:find).with("1").and_return(@letter) > >> >> >> >> > ? ?puts(@letter) > >> >> >> >> > ? ?do_get > >> >> >> >> > ?end > > >> >> >> >> > ?it "should assign the found letter for the view" do > >> >> >> >> > ? ?# uncommenting will allow to pass > >> >> >> >> > ? ?# @user.letters.should_receive(:find).with("1").and_return > >> >> >> >> > (@letter) > >> >> >> >> > ? ?do_get > >> >> >> >> > ? ?assigns[:letter].should equal(@letter) > >> >> >> >> > ?end > > >> >> >> >> > ?it "should render show template" do > >> >> >> >> > ? ?do_get > >> >> >> >> > ? ?response.should render_template("show") > >> >> >> >> > ?end > > >> >> >> >> > end > > >> >> >> >> > On Jul 22, 9:13?am, David Chelimsky <dchelim... at gmail.com> wrote: > >> >> >> >> >> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote: > >> >> >> >> >> > How do I spec this following example from the Agile Rails Book listed > >> >> >> >> >> > below. I am doing a similar thing in my controller and when I > >> >> >> >> >> > attempted to change it to the collection way of doing the find I am > >> >> >> >> >> > unable to get my spec to pass though I know it is working fine as my > >> >> >> >> >> > cucumber features are passing > > >> >> >> >> >> > old rails way: > > >> >> >> >> >> > def show > >> >> >> >> >> > @order = Order.find(params[:id]) > >> >> >> >> >> > end > > >> >> >> >> >> > new rails way collection-based: > > >> >> >> >> >> > def show > >> >> >> >> >> > id = params[:id] > >> >> >> >> >> > @order = @user.orders.find(id) > > >> >> >> >> >> This code is inherently untestable in an isolated/granular way. Your > >> >> >> >> >> options are: > > >> >> >> >> >> * write higher level specs that use real data > >> >> >> >> >> ? * pros: simplicity and clarity in both code and specs > >> >> >> >> >> ? * cons: brittle due to runtime dependency on correct models, runs slow > > >> >> >> >> >> * write a very invasive spec with complex setup and instance_eval to > >> >> >> >> >> set up the @user > >> >> >> >> >> ? * pros: runs fast, no runtime dependency on correct models > >> >> >> >> >> ? * cons: brittle due to dependency on internals, complex > > >> >> >> >> >> * refactor the code to make it easier to spec > >> >> >> >> >> ? * pros: more highly decoupled code, simpler specs, fast > >> >> >> >> >> ? * cons: more work up front, may disregard some of what Rails has to offer > > >> >> >> >> >> Note that the first two options are both brittle, but for different > >> >> >> >> >> reasons. The first is brittle due to a runtime dependency. That means > >> >> >> >> >> that when you run the spec the model has to be working correctly for > >> >> >> >> >> the spec to pass, and a failure could be due to a problem in the model > >> >> >> >> >> or in the controller. > > >> >> >> >> >> The second is due to a code dependency. That means that when you want > >> >> >> >> >> to change this code, the spec will have to change as well. This is > >> >> >> >> >> true of any case in which you use mocks or stubs to varying degrees, > >> >> >> >> >> and that comes with its own tradeoffs. In this case, the necessary > >> >> >> >> >> stubbing would be complex and invasive enough that it would be a > >> >> >> >> >> concern to me. > > >> >> >> >> >> Getting to your original question - what does your spec look like now, > >> >> >> >> >> and what failure message are you getting? > > >> >> >> >> >> Cheers, > >> >> >> >> >> David > > >> >> >> >> >> > rescue > >> >> >> >> >> > redirect_to :action => "index" > >> >> >> >> >> > end > > >> _______________________________________________ > >> rspec-users mailing list > >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > > rspec-users mailing list > > rspec-us... at rubyforge.org > >http://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users