<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Q. Why does code which defines a context work in the <tt>controller_spec</tt>
file and not in a 'require'd helper file?<br>
<br>
A. Because spec uses the filename to tell it what type of context
(:controller, :model) it is creating.<br>
<br>
Fix: use the (undocumented?) second parameter to <tt>#context(), </tt><b><tt>:context_type
=> :controller.<br>
<br>
</tt></b>Quite how this works, I do not know; the rdocs don't mention
it and according to the source context doesn't take a second argument
(except a block). My Ruby-fu isn't up to explaining it; if anyone else
would like to do so that would be nice.<b><br>
</b><br>
Hope this helps someone else save a half hour or so.<br>
<br>
Rgds,<br>
Jerry<br>
<br>
Further details:<br>
<br>
If I define a method which dynamically constructs a context in my
controller_spec.rb file it works fine:<br>
<br>
<tt>def restful_edit_specs(resource)<br>
context "GET /#{resource}/:id;edit (:edit)" do <br>
controller_name resource<br>
<br>
resource = resource.to_s<br>
sym = resource.singularize<br>
klass = resource.classify<br>
<br>
setup do<br>
@mock = mock_model sym # based on
<a class="moz-txt-link-freetext" href="http://metaclass.org/2006/12/22/making-a-mockery-of-activerecord">http://metaclass.org/2006/12/22/making-a-mockery-of-activerecord</a><br>
@model = Object.const_get(klass)<br>
@model.should_receive(:find).with(@mock.id).and_return(@mock)<br>
end<br>
<br>
def do_get() get :edit, :id => @mock.id end<br>
<br>
specify "should be successful" do<br>
do_get<br>
response.should_be_success<br>
end<br>
specify "should render edit.rhtml" do<br>
do_get<br>
controller.should_render :edit<br>
end<br>
specify "should find the #{klass} requested" do<br>
@model.should_receive(:find).and_return(@mock)<br>
do_get<br>
end<br>
specify "should assign the found #{klass} for the view" do<br>
do_get<br>
assigns(sym).should_equal @mock<br>
end<br>
end<br>
end<br>
<br>
restful_edit_specs(:assessments)<br>
<br>
</tt>This all works fine when defined in the xx_controller_spec.rb file.<br>
<br>
But if I move the exact same code to a helper file and require it, spec
gets confused:<br>
<br>
<tt>.../rspec-0.7.5.1/lib/spec/expectations/sugar.rb:13:in `call':
undefined method `controller_name' for
#<Spec::Runner::ContextEvalModule:0xb70496a8> (NoMethodError)<br>
... etc etc...<br>
</tt><br>
Clearly, there's some magic involved which means the context does not
know what it's about (it was at this point in typing my original plea
for help that I remembered seeing the :context_type parameter in the
specs for the rspec_on_rails plugin itself).<br>
<br>
Changing the context line to<br>
<br>
<tt> </tt><b><tt>context "GET /#{resource}/:id;edit (:edit)", </tt><tt>:context_type
=> :controller do<br>
<br>
</tt></b>allows the specs to function as ex-spec-ted.<b><tt><br>
</tt></b>
</body>
</html>