[rspec-users] [RSpec][RJS] Problem with specing create.rjs in controller_spec

Zach Dennis zach.dennis at gmail.com
Fri Feb 27 13:33:33 EST 2009


Hi Evgeny,

I would like to encourage you to verify your expectations that the JS
is functioning in the browser, using tools like Webrat and Selenium.
IMO spec'ing RJS files provides little value in the grand scheme of
things, yet those specs build up a heavy maintenance overhead.

With RJS you are usually either generating javascript manually and
sending them to the "page" object, or you are using Rails API for
invoking things in javascript. Either way you're unable to actually
verify the JS is doing what you want and there's no design value
coming from things like, "page[:foo].hide" or "page <<
'doSomething()', and there's no verification of the behaviour
expected.

A wonderful alternative is going the unobtrusive javascript route, and
keeping JS in JS files, and then having your app send back JSON or
having your RJS files merely make a function call to JS. Now when you
use Webrat + Selenium you're able to ensure the JS you implemented is
doing what it should be doing on the page.


On Fri, Feb 27, 2009 at 6:10 AM, Evgeny Bogdanov
<evgeny.bogdanov at gmail.com> wrote:
> Thank you David.
> I decided to test rjs file separately of the controller, so I created
> a spec for it and put it into views folder.
> In rjs file the partial is called, however I would like to mock it.
> 1) I tried to use in spec the line:
> template.should_receive(:render).with(:partial => "comments/
> comment").and_return(true)
> but partial is still called.
> 2) another approach would be to mock the methods of the "page" object,
> but I couldn't find out how to do it.
> 3) How do I make sure that "#add_comment" was made "hidden" after the
> partial was called?
> response.should have_tag("#add_comment") after "render :template"
> doesn't work.
>
> Thank you in advance and sorry for the long list.
> Evgeny
> PS. Are these questions covered in the book: "The RSpec Book:
> Behaviour Driven Development with RSpec, Cucumber, and Friends"?
>
> ===== comment_create_rjs_spec.rb
> describe "comment create rjs" do
>  it "should hide add_comment div" do
>    comment = mock_model(Comment, :id => "1")
>
>    assigns[:comment] = comment
>    ???template.should_receive(:render).with(:partial => "comments/
> comment").and_return(true)
>    render :template => 'comments/create.rjs'
>  end
> end
> ===create.rjs
> comment_id = "comment_"+ at comment.id.to_s
>
> page['add_comment'].hide
> page.insert_html :top, 'comments_list', :partial => "comments/
> comment", :locals => {:comment => @comment, :item => @item}
> page.visual_effect :highlight, comment_id, :duration => 1
> ----------------------------------------------------
> On Feb 26, 5:25 pm, David Chelimsky <dchelim... at gmail.com> wrote:
>> On Thu, Feb 26, 2009 at 10:01 AM, Evgeny Bogdanov
>>
>>
>>
>> <evgeny.bogda... at gmail.com> wrote:
>> > Could somebody please explain me what I am doing wrong.
>> > I am trying to spec create.rjs file, that is returned from my
>> > controller.
>>
>> > render_template("create.rjs") works just fine,
>>
>> > however have_rjs fails with the following error:
>> > 'CommentsController while posting a comment renders a create.rjs
>> > template when comment is successfully created in ajax request' FAILED
>> > No RJS statement that replaces or inserts HTML content.
>>
>> > Thank you!
>> > Evgeny
>>
>> > =====controller
>> >  def create
>> >    @comment.save
>>
>> >    respond_to do |format|
>> >          format.js
>> >    end
>> >  end
>>
>> > =====create.rjs
>> > comment_id = "comment_"+... at comment.id.to_s
>>
>> > page['add_comment'].hide
>> > page.insert_html :top, 'comments_list', :partial => "comments/
>> > comment", :locals => {:comment => @comment, :item => @item}
>> > page.visual_effect :highlight, comment_id, :duration => 1
>>
>> > =====spec file
>> >  it "renders a create.rjs template when comment is successfully
>> > created in ajax request" do
>> >    request.env["HTTP_ACCEPT"] = "application/javascript"
>> >    post :create, :item_id => 1, :item_type => "Space", :comment =>
>> > {:content => "text"}
>>
>> >    response.should render_template("create")
>> >    response.should have_rjs
>> >  end
>>
>> Controller specs, by default, do not render templates. If you want to
>> specify the contents of a template from your controller spec, tell it
>> to integrate_views (hmmm - maybe we should change that to
>> render_views???)
>>
>> describe MyController do
>>   integrate_views
>>   it "does something" do
>>     ...
>>   end
>> end
>>
>> HTH,
>> David
>> _______________________________________________
>> 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
>



-- 
Zach Dennis
http://www.continuousthinking.com
http://www.mutuallyhuman.com


More information about the rspec-users mailing list