[rspec-users] assert_select - to do negative tests - need help with syntax please :)

David Chelimsky dchelimsky at gmail.com
Wed Oct 12 07:20:44 EDT 2011

On Oct 12, 2011, at 12:58 AM, Gordon wrote:

> Hi all,
>  I am trying to figure out how to use assert_select properly.
> When I created a new resource in rails 3 called Brands, the view specs for brands had a test which read:
>    # Run the generator again with the --webrat flag if you want to
> use webrat matchers
>    assert_select "form", :action => brands_path, :method => "post" do
>      assert_select "input#brand_name", :name => "brand[name]"
>      assert_select "input#brand_description", :name =>
> "brand[description]"
>      assert_select "input#brand_created_by", :name =>
> "brand[created_by]"
>    end
> With my project, I do not want the "created by" attribute to be set from the new.html.erb entry form.
> I read http://content.labnotes.org/assert_select/assert_select.html and figured I need to use the 'false' equality operator.

That's old. Check out http://api.rubyonrails.org/classes/ActionDispatch/Assertions/SelectorAssertions.html#method-i-assert_select for the latest.


> Alas, my attempts at using it failed.
> For  a spec/statement such as 'assert_select
> input#brand_created_by", :name => "brand[created_by]',
> I would think that input#brand_created_by would be the 'element' and
> the 'selector' combined.


> a) assert_select "input#brand_created_by", :name =>
> "brand[created_by]", '', false   --> spec/views/brands/
> new.html.erb_spec.rb:53: syntax error, unexpected ',', expecting
> tASSOC (SyntaxError) …me => "brand[created_by]", '', false

This is a problem with Ruby argument ordering working against the expressiveness you're looking for. Keyword arguments have to come last. So you can say:

  do_something 1, 2, :a, thing, :b => 3

but you can't say

  do_something 1, :a, thing, :b => 3, 2

What _will_ work is this:

  assert_select "input#brand_created_by", false

This leaves out the :name argument, but you don't need it IMO. If you really want it, you'd have to do this:

  assert_select "input#brand_created_by", false, :name => "brand[created_by]"

But that feels really awkward to me, since the negative assertion is expressed in the middle of the argument list

> Can someone please tell me what the right syntax is for saying, "i
> expect not to see the brand[created_by]" input attribute at all in the
> rendered form for adding new entries?

  rendered.should_not have_selector("input#brand_created_by") # ;)

You need Capybara for that, of course, but I think it's easier to grok than:

  assert_select "input#brand_created_by", false


More information about the rspec-users mailing list