<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
James,<br>
<br>
the gem is converting your hash to an array of arrays when it builds
the mock expectation.&nbsp; This is really an artifact of Ruby's hash/array
handling - the code in the gem looks perfectly reasonable, it just has
this side-effect.<br>
<br>
If you check out <tt>$GEM_DIR/rspec-0.7.5.1/lib/spec/mocks/message_expectation.rb</tt>
you will see that <tt>#with()</tt> passes your hash to a new instance
of <i>ArgumentExpectation,</i> which is defined in <tt>$GEM_DIR/rspec-0.7.5.1/lib/spec/mocks/argument_expectation.rb</tt>
. &nbsp; There you will see that a hash is a <i>LiteralArgConstraint</i>
(as opposed to <font color="#3366ff">:anything,</font> <font
 color="#3366ff">:numeric</font>, and the other parameters that <tt>#with()</tt>
accepts).&nbsp; The interesting code is around line 89 in <tt>#process_arg_constraints()</tt>
where your hash is converted one item at a time using the normal Ruby <i>Enumerable</i>
routine <tt>#collect()</tt>.&nbsp; Which is where the side-effect happens.<br>
<br>
Try this in irb:<br>
<br>
<pre>$ irb
irb(main):001:0&gt; @params = {:cn =&gt; "Bilbo Baggins", :telephoneNumber =&gt; "416-277-4418", :mail =&gt; <a class="moz-txt-link-rfc2396E" href="mailto:bilbo@baggins.com">"bilbo@baggins.com"</a>}
</pre>
<pre>irb(main):002:0&gt; @params.collect{|c| c}</pre>
<pre>=&gt; [[:cn, "Bilbo Baggins"], [:telephoneNumber, "416-277-4418"], [:mail, <a class="moz-txt-link-rfc2396E" href="mailto:bilbo@baggins.com">"bilbo@baggins.com"</a>]]</pre>
<pre>irb(main):003:0&gt; </pre>
<br>
and you will see that your hash has been converted into the array of
arrays.&nbsp; That's what happening in the gem once you strip away <tt>#convert_constraint()</tt>
etc.<br>
<br>
You have a choice of workarounds; the simplest of which is a separate
array <tt>@params_for_mock_user = @params.collect</tt> ; (null body
returns each element as above) and then <tt>User.should_receive(:update_attributes).with(@params_for_mock_user).<br>
<br>
</tt>It might be worth <a
 href="http://rubyforge.org/tracker/?atid=3152&amp;group_id=797&amp;func=browse">filing
an RFE</a> on this as it's counter-intuitive and likely to bite others
as well<br>
<tt><br>
</tt>Hope this helps.<br>
<br>
Rgds,<br>
&nbsp; Jerry<br>
<br>
<br>
James Hughes wrote:
<blockquote
 cite="mid765a2c230702141600j33b98be7w22dab72e5c2cbc10@mail.gmail.com"
 type="cite">
  <pre wrap="">Hi,

I have this setup block:

  setup do
    session[:login] = 'jhughes'
    @user = mock("user")
    User.stub!(:find).and_return(@user)
    @params = {:cn =&gt; "Bilbo Baggins",
      :telephoneNumber =&gt; "416-277-4418",
      :mail =&gt; <a class="moz-txt-link-rfc2396E" href="mailto:bilbo@baggins.com">"bilbo@baggins.com"</a>}
  end

And then this spec:

  specify "should update and save the attributes for user" do
    @user.should_receive(:update_attributes).with(@params).and_return(true)
    post :update, :id =&gt; "jhughes", :user =&gt; @params
  end

This fails like this:

Mock 'user' expected :update_attributes with ([:telephoneNumber,
"416-277-4418"], [:mail, <a class="moz-txt-link-rfc2396E" href="mailto:bilbo@baggins.com">"bilbo@baggins.com"</a>], [:cn, "Bilbo Baggins"])
but received it with ({"cn"=&gt;"Bilbo Baggins",
"telephoneNumber"=&gt;"416-277-4418", "mail"=&gt;<a class="moz-txt-link-rfc2396E" href="mailto:bilbo@baggins.com">"bilbo@baggins.com"</a>})

Puzzling, especially since inspecting the @params variable just before
the should_receive shows the expected hash.

What am I doing wrong?

James
_______________________________________________
rspec-users mailing list
<a class="moz-txt-link-abbreviated" href="mailto:rspec-users@rubyforge.org">rspec-users@rubyforge.org</a>
<a class="moz-txt-link-freetext" href="http://rubyforge.org/mailman/listinfo/rspec-users">http://rubyforge.org/mailman/listinfo/rspec-users</a>
  </pre>
</blockquote>
</body>
</html>