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 :
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 ?
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.
On Sat, Feb 28, 2009 at 11:49 AM, Mathieu LeFrancois [email protected] 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.
Hi Mathieu,
params.each {
I am trying to mock the crits local variable. Here is what the rspec
concrete example because the term “crits” means nothing to me. What is
end
before(:each) do
SomeOtherObject.stub!(:parse_crits).and_return stub(“crits”)