Hi, I need help to spec a local variable in a controller. I have been wandering how I can do that since all I have done so far is useless. Note that the code is in a controller and that it is not yet finished since I am trying to spec it as I develop it. Here is what the code should look like when it is finished : ... crits = {} params.each { |key, val| crits[key.to_sym] = StringUtils.remove_chars(val).upcase if not (cle == "controller" || cle == "action") } if crits[:name].nil? add_where(where_clause, crits[:name]) end ... I am trying to mock the crits local variable. Here is what the rspec looks like so far : @mock_crits = mock(Hash, { :name => ''Steve'' }) assigns(:crits) = @mock_crits First, I can not seem to have control on the params array. How can I mock this array ? Also, I also can not seem to have control on the crits local variable when I try to spec the if crits[:name].nil?. Is this a bad way to code ? Can anyone explain this ? Many thanks in advance. Mathieu
Jonathan Linowes
2009-Feb-27 21:13 UTC
[rspec-users] How do you mock a local variable (#2) ?
if you moved the code that defines crits into a method then you could stub the method crits = define_crits then controller.stub!(:define_crits).and_return( { :name => ''Steve'' }) On Feb 27, 2009, at 3:35 PM, MathLef wrote:> Hi, > > I need help to spec a local variable in a controller. I have been > wandering how I can do that since all I have done so far is useless. > Note that the code is in a controller and that it is not yet finished > since I am trying to spec it as I develop it. Here is what the code > should look like when it is finished : > > ... > crits = {} > params.each { > |key, val| > crits[key.to_sym] = StringUtils.remove_chars(val).upcase if not > (cle == "controller" || cle == "action") > } > > if crits[:name].nil? > add_where(where_clause, crits[:name]) > end > ... > > I am trying to mock the crits local variable. Here is what the rspec > looks like so far : > > @mock_crits = mock(Hash, { :name => ''Steve'' }) > assigns(:crits) = @mock_crits > > First, I can not seem to have control on the params array. How can I > mock this array ? Also, I also can not seem to have control on the > crits local variable when I try to spec the if crits[:name].nil?. Is > this a bad way to code ? Can anyone explain this ? > > Many thanks in advance. > Mathieu > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users____________________________________________________________ Click here for great quotes from top international movers! http://thirdpartyoffers.netzero.net/TGL2241/fc/BLSrjpYZJC3f6oCp59jmvk73w3RQPFmDYOsliJp8Zb9RMPdh9WHBfJtdXTC/
On Feb 27, 2009, at 3:35 PM, MathLef wrote:> Hi, > > I need help to spec a local variable in a controller. I have been > wandering how I can do that since all I have done so far is useless. > Note that the code is in a controller and that it is not yet finished > since I am trying to spec it as I develop it. Here is what the code > should look like when it is finished : > > ... > crits = {} > params.each { > |key, val| > crits[key.to_sym] = StringUtils.remove_chars(val).upcase if not > (cle == "controller" || cle == "action") > } > > if crits[:name].nil? > add_where(where_clause, crits[:name]) > end > ... > > I am trying to mock the crits local variable. Here is what the rspec > looks like so far :Don''t try to spec local variables (in fact, ruby doesn''t even give you a way, AFAIK). You are better off testing this thing in a black box fashion by passing in different params to the action and seeing the result on the query. Scott> > > @mock_crits = mock(Hash, { :name => ''Steve'' }) > assigns(:crits) = @mock_critsOnly use assigns to see the results of setting an ivar (in rails). setting assigns[:foo] before the action won''t do you much good, I''m afraid.> > > First, I can not seem to have control on the params array. How can I > mock this array ? Also, I also can not seem to have control on theDon''t mock it, just pass it in: get :my_action, :some => :hash Scott> > crits local variable when I try to spec the if crits[:name].nil?. Is > this a bad way to code ? Can anyone explain this ? > > Many thanks in advance. > Mathieu > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
On Fri, Feb 27, 2009 at 3:35 PM, MathLef <mlefrancois19 at gmail.com> wrote:> Hi,Hi Mathieu,> > I need help to spec a local variable in a controller. I have been > wandering how I can do that since all I have done so far is useless. > Note that the code is in a controller and that it is not yet finished > since I am trying to spec it as I develop it. Here is what the code > should look like when it is finished : > > ... > crits = {} > params.each { > |key, val| > crits[key.to_sym] = StringUtils.remove_chars(val).upcase if not > (cle == "controller" || cle == "action") > } > > if crits[:name].nil? > add_where(where_clause, crits[:name]) > end > ... > > I am trying to mock the crits local variable. Here is what the rspec > looks like so far : > > @mock_crits = mock(Hash, { :name => ''Steve'' }) > assigns(:crits) = @mock_crits > > First, I can not seem to have control on the params array. How can I > mock this array ?You can control "params" by passing in a hash representative of query parameters from a request. ie: get :action_name, :foo => "bar", :bar => "baz", :baz => "banana"> Also, I also can not seem to have control on the > crits local variable when I try to spec the if crits[:name].nil?. Is > this a bad way to code ? Can anyone explain this ?I think you have some room to adjust the design a little to make your controller responsible for doing less, and making your model responsible for doing more. This will open up less complicated ways of spec''ing both your controller and the model. It''s hard to give a concrete example because the term "crits" means nothing to me. What is the intention behind building up the crits hash? Also, what does ''cle == "controller" || cle == "action"'' represent? Not knowing anything else I would probably try to make your controller code look like: def your_action crits = SomeOtherObject.parse_crits params.except(:controller, :action) FooModel.find_stuff_by_crits crits end My only disclaimer on this is that I don''t know anything about your code other than what you posted, so it is up to you to find a good home for the appropriate methods and logic. This approach lets you spec the parsing of "crits" separate from the controller action while being able to ensure the controller action did in fact parse them. Here''s a sample spec for the #your_action I posted above: before(:each) do SomeOtherObject.stub!(:parse_crits) end it "should parse crits from params" do SomeOtherObject.should_receive(:parse_crits).with("foo" => "bar") get :your_action, "foo" => "bar" end it "should have find whatever it is you''re looking for" do crits_stub = stub("crits") SomeOtherObject.stub!(:parse_crits).and_return stub("crits") FooModel.should_receive(:find_stuff_by_crits).with(crits_stub) get :your_action end This makes the controller spec much easier to gr0k and write! Although I urge you to find better names for "crits" and to hide some of the functionality behind intention-revealing interfaces. It not only makes your code easier for you to read and maintain, but it does that for anyone who has to look at, either on this mailing list, or other developers who will come back and maintain the code.> > Many thanks in advance. > Mathieu > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com
Mathieu LeFrancois
2009-Feb-28 16:49 UTC
[rspec-users] How do you mock a local variable (#2) ?
Zach, the "cle" variable you ask for should have been read as "key". The word "cl?" is the French translation for the word "key". I changed it, but obviously forgot instances, for you guys to understand the code since you might not be familiar with French. ;-) Thank you all for your good advices. I am looking forward to learn how to work with rspec properly ! Mathieu 2009/2/28 Zach Dennis <zach.dennis at gmail.com>> On Fri, Feb 27, 2009 at 3:35 PM, MathLef <mlefrancois19 at gmail.com> wrote: > > Hi, > > Hi Mathieu, > > > > > I need help to spec a local variable in a controller. I have been > > wandering how I can do that since all I have done so far is useless. > > Note that the code is in a controller and that it is not yet finished > > since I am trying to spec it as I develop it. Here is what the code > > should look like when it is finished : > > > > ... > > crits = {} > > params.each { > > |key, val| > > crits[key.to_sym] = StringUtils.remove_chars(val).upcase if not > > (cle == "controller" || cle == "action") > > } > > > > if crits[:name].nil? > > add_where(where_clause, crits[:name]) > > end > > ... > > > > I am trying to mock the crits local variable. Here is what the rspec > > looks like so far : > > > > @mock_crits = mock(Hash, { :name => ''Steve'' }) > > assigns(:crits) = @mock_crits > > > > First, I can not seem to have control on the params array. How can I > > mock this array ? > > You can control "params" by passing in a hash representative of query > parameters from a request. > > ie: get :action_name, :foo => "bar", :bar => "baz", :baz => "banana" > > > Also, I also can not seem to have control on the > > crits local variable when I try to spec the if crits[:name].nil?. Is > > this a bad way to code ? Can anyone explain this ? > > I think you have some room to adjust the design a little to make your > controller responsible for doing less, and making your model > responsible for doing more. This will open up less complicated ways of > spec''ing both your controller and the model. It''s hard to give a > concrete example because the term "crits" means nothing to me. What is > the intention behind building up the crits hash? > > Also, what does ''cle == "controller" || cle == "action"'' represent? > > Not knowing anything else I would probably try to make your controller > code look like: > > def your_action > crits = SomeOtherObject.parse_crits params.except(:controller, :action) > FooModel.find_stuff_by_crits crits > end > > My only disclaimer on this is that I don''t know anything about your > code other than what you posted, so it is up to you to find a good > home for the appropriate methods and logic. > > This approach lets you spec the parsing of "crits" separate from the > controller action while being able to ensure the controller action did > in fact parse them. Here''s a sample spec for the #your_action I posted > above: > > before(:each) do > SomeOtherObject.stub!(:parse_crits) > end > > it "should parse crits from params" do > SomeOtherObject.should_receive(:parse_crits).with("foo" => "bar") > get :your_action, "foo" => "bar" > end > > it "should have find whatever it is you''re looking for" do > crits_stub = stub("crits") > SomeOtherObject.stub!(:parse_crits).and_return stub("crits") > FooModel.should_receive(:find_stuff_by_crits).with(crits_stub) > get :your_action > end > > This makes the controller spec much easier to gr0k and write! Although > I urge you to find better names for "crits" and to hide some of the > functionality behind intention-revealing interfaces. It not only makes > your code easier for you to read and maintain, but it does that for > anyone who has to look at, either on this mailing list, or other > developers who will come back and maintain the code. > > > > > Many thanks in advance. > > Mathieu > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > -- > Zach Dennis > http://www.continuousthinking.com > http://www.mutuallyhuman.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20090228/c9093474/attachment-0001.html>
On Sat, Feb 28, 2009 at 11:49 AM, Mathieu LeFrancois <mlefrancois19 at gmail.com> wrote:> Zach, the "cle" variable you ask for should have been read as "key". The > word "cl?" is the French translation for the word "key". I changed it, but > obviously forgot instances, for you guys to understand the code since you > might not be familiar with French. ;-)Ah okay! Pardon my ignorance. I did take some french years ago, but at the time I was too stupid in my youth to realize that it would be amazing to learn and to learn well.> > Thank you all for your good advices. I am looking forward to learn how to > work with rspec properly ! > Mathieu > > 2009/2/28 Zach Dennis <zach.dennis at gmail.com> >> >> On Fri, Feb 27, 2009 at 3:35 PM, MathLef <mlefrancois19 at gmail.com> wrote: >> > Hi, >> >> Hi Mathieu, >> >> > >> > I need help to spec a local variable in a controller. I have been >> > wandering how I can do that since all I have done so far is useless. >> > Note that the code is in a controller and that it is not yet finished >> > since I am trying to spec it as I develop it. Here is what the code >> > should look like when it is finished : >> > >> > ... >> > crits = {} >> > params.each { >> > ?|key, val| >> > ? crits[key.to_sym] = StringUtils.remove_chars(val).upcase if not >> > (cle == "controller" || cle == "action") >> > } >> > >> > if crits[:name].nil? >> > ?add_where(where_clause, crits[:name]) >> > end >> > ... >> > >> > I am trying to mock the crits local variable. Here is what the rspec >> > looks like so far : >> > >> > @mock_crits = mock(Hash, { :name => ''Steve'' }) >> > assigns(:crits) = @mock_crits >> > >> > First, I can not seem to have control on the params array. How can I >> > mock this array ? >> >> You can control "params" by passing in a hash representative of query >> parameters from a request. >> >> ie: get :action_name, :foo => "bar", :bar => "baz", :baz => "banana" >> >> > Also, I also can not seem to have control on the >> > crits local variable when I try to spec the if crits[:name].nil?. Is >> > this a bad way to code ? Can anyone explain this ? >> >> I think you have some room to adjust the design a little to make your >> controller responsible for doing less, and making your model >> responsible for doing more. This will open up less complicated ways of >> spec''ing both your controller and the model. It''s hard to give a >> concrete example because the term "crits" means nothing to me. What is >> the intention behind building up the crits hash? >> >> Also, what does ''cle == "controller" || cle == "action"'' represent? >> >> Not knowing anything else I would probably try to make your controller >> code look like: >> >> ?def your_action >> ? ?crits = SomeOtherObject.parse_crits params.except(:controller, :action) >> ? ?FooModel.find_stuff_by_crits crits >> ?end >> >> My only disclaimer on this is that I don''t know anything about your >> code other than what you posted, so it is up to you to find a good >> home for the appropriate methods and logic. >> >> This approach lets you spec the parsing of "crits" separate from the >> controller action while being able to ensure the controller action did >> in fact parse them. Here''s a sample spec for the #your_action I posted >> above: >> >> ?before(:each) do >> ? ?SomeOtherObject.stub!(:parse_crits) >> ?end >> >> ?it "should parse crits from params" do >> ? ? SomeOtherObject.should_receive(:parse_crits).with("foo" => "bar") >> ? ? get :your_action, "foo" => "bar" >> ?end >> >> ?it "should have find whatever it is you''re looking for" do >> ? ?crits_stub = stub("crits") >> ? ?SomeOtherObject.stub!(:parse_crits).and_return stub("crits") >> ? ?FooModel.should_receive(:find_stuff_by_crits).with(crits_stub) >> ? ?get :your_action >> ?end >> >> This makes the controller spec much easier to gr0k and write! Although >> I urge you to find better names for "crits" and to hide some of the >> functionality behind intention-revealing interfaces. It not only makes >> your code easier for you to read and maintain, but it does that for >> anyone who has to look at, either on this mailing list, or other >> developers who will come back and maintain the code. >> >> > >> > Many thanks in advance. >> > Mathieu >> > _______________________________________________ >> > rspec-users mailing list >> > rspec-users at rubyforge.org >> > http://rubyforge.org/mailman/listinfo/rspec-users >> > >> >> >> >> -- >> Zach Dennis >> http://www.continuousthinking.com >> http://www.mutuallyhuman.com >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > >-- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com