Testing RJS with assert_select_rjs

I am surprised to find little about testing RJS in rails, with the exception of ARTS. However, assert_select_rjs seems to be the replacement to ARTS. This is nice, as we have now one less plugin to worry about. (I am of the opinion that testing plugins should be integrated into core if it is used in more than one test)

I’ll show you one example.

Let’s say that we have scaffolded our controllers, and now have a RJS function that we want to call when we destroy a membership. We first create our test

memberships_controller_test.rb
[source:ruby]
def test_should_destroy_membership
old_count = Membership.count
delete :destroy, :id => 1
assert_equal old_count-1, Membership.count
assert_response :success
assert_select_rjs :replace_html, “membership-action”
end[/source]

I am just testing if replace_html was called on the ‘membership-action’ element, without regard to what content is replaced into. If you want to test the content being replaced, pass the value to be compared as the second parameter of assert_select_rjs. E.g.

[source:ruby] assert_select_rjs :replace_html, “membership-action”, “Some Content”[/source]

Test and watch it go red.

Now we create our RJS template to make the test go green. The content can be anything, since I did not test for equality of the content to be replaced.

memberships/destroy.rjs
[source:ruby]page.replace_html ‘membership-action’, :partial => ‘memberships/join_link'[/source]

Run the test and feel the green.

Looking under the hood of assert_select_rjs, it seems that it is taking a copy of @response.body, and then running a Regular Expression match with the test values. Something worth knowing.

It also checks for content-type=text/javascript, so make sure your @response is returning javascript, otherwise the test will fail in a non-obvious way. If you forgot to include format.js in the controller, the assertion error message will be displayed as

“No RJS statement that replaces or inserts HTML content”

Just remember to put format.js in your controller, and you should be alright.

7 Responses to “Testing RJS with assert_select_rjs”

  1. David Jones Says:

    You should be able to clean the membership_controller_test up by using asset_difference().

    This is a fairly new method. Changeset here: http://dev.rubyonrails.org/browser/trunk/activesupport/lib/active_support/core_ext/test/difference.rb?rev=6647

    Instead of

    old_count = Membership.count
    assert_equal old_count-1,
    Membership.count

    You can do something more elegant, like this:


    assert_difference 'Membership.count' do
    delete :destroy, :id => 1
    end

  2. David Jones Says:

    Ops, the before code is like this (not like the one above):


    old_count = Membership.count
    delete :destroy, :id => 1
    assert_equal old_count-1, Membership.count

  3. Thong Kuah Says:

    Thanks for the improvement. It would make the code more elegant. Note though that assert_difference is for rails edge (i.e > 1.2.3)

  4. Declan Says:

    I have been trying to use…

    assert_select_rjs :replace_html, “membership-action”, “Some Content”

    … but it’s not working. For example,

    assert_select_rjs :replace_html, “happy_div”, “blah”

    … will always pass regardless of whether the html content matches or not.

  5. Thong Kuah Says:

    Declan,

    I had the rails syntax confused with the ARTS plugin. in rails, you would do

    assert_select_rjs :replace_html, “membership-action” do
    assert_select ‘span’, :text => ‘Some content’
    end

    You would have to wrap the content in a html element, like a span. I am not sure if assert_select can find text nodes

  6. Tim Haines Says:

    Thanks for this post Thong. Currently another cause of the ““No RJS statement that replaces or inserts HTML content” message is if your show or hide assertions don’t match what’s being returned. Just logged a bug for this as it seems a very poor error message -> http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/931

    I found I didn’t need format.js for the assertions to work. Do you think format.js should be included anyway to ensure the header is set correctly?

  7. Brent Sowers Says:

    Anyone know how to test RJS that returns Javascript functions to call instead of HTML updates? I’ve looked all around and can’t seem to find any info on this. I think you could do this with ARTS but I can’t download ARTS anywhere.

Leave a Reply


http://www.canakkaleruhu.org http://www.vergimevzuati.org http://www.finansaldenetci.com http://www.securityweb.org http://www.siyamiozkan.org http://www.fatmaozkan.com http://www.sgk.biz.tr http://www.denetci.gen.tr http://www.bagimsizdenetim.biz.tr http://www.mevzuat.biz.tr http://www.security.biz.tr http://www.sorgulatr.com http://www.kanunlar.biz http://www.prsorgu.net http://www.sirabul.com http://www.emekliol.org http://www.coklupagerank.com http://www.coklupagerank.net http://www.coklupagerank.org http://www.prsorgu.org http://www.scriptencode.com http://www.sirabul.net http://www.sirabul.org http://www.sitenizanaliz.com http://www.seoisko.com http://www.seomavi.com http://www.scriptencode.net http://www.scriptencode.org