Symbols in strings out in stubbed response

I have a test that looks like this:

describe ChannelsController, “GET edit” do
it “assigns the greetings summary” do
summary = {:total => 139, :submitted => 97, :published =>
82, :removed => 12}
Greeting.stub(:summary).and_return summary
get :index
assigns(:summary).should eq(summary)
end
end

It fails with the following:
expected {:total=>139, :submitted=>97, :published=>82, :removed=>12}
got {“total”=>139, “submitted”=>97, “published”=>82,
“removed”=>12}

The code that is getting called is this:

ChannelsController

def index
@summary = Greeting.summary
end

Greeting

def self.summary
{
:total => self.count,
:submitted => self.submitted.count,
:published => self.published.count,
:removed => self.removed.count
}
end

I expected this example to pass, and I can’t figure out if I should be
doing something differently either in the code itself or in the test.

Any insights?

Thanks,
Katrina

On Oct 23, 2010, at 5:40 PM, Katrina wrote:

end
@summary = Greeting.summary
end
The definition of self.summary shouldn’t matter here since it’s being
stubbed in the example.

I expected this example to pass,

I would have too, but it looks like Rails is converting hashes that get
assigned to views to HashWithIndifferentAccess, which only looks at
Strings in its implementation of ==.

Take a look at hash_with_indifferent_access_double_equals.sh · GitHub.

The problem here is that it would be unwise for
HashWithIndifferentAccess to implement == any differently, because you’d
end up with surprising results (a == b would pass, but b == a would
fail).

So you have to assume that the keys are Strings regardless of what you
set in the example. Therefore, I’d recommend setting Strings in the
example in order to keep sane :slight_smile:

HTH,
David

On Oct 23, 1:40pm, Katrina [email protected] wrote:

[…]
It fails with the following:
expected {:total=>139 #…
got {“total”=>139 #…
[…}

I think the problem you’re having is that you’re expecting/stubbing
symbols for your keys, but the keys for parameters are strings.

Good luck,
Pete

On Oct 23, 2010, at 7:29 PM, Peter H. wrote:

On Oct 23, 1:40 pm, Katrina [email protected] wrote:

[…]
It fails with the following:
expected {:total=>139 #…
got {“total”=>139 #…
[…}

I think the problem you’re having is that you’re expecting/stubbing
symbols for your keys, but the keys for parameters are strings.

This hash wasn’t a params hash - it was coming directly from a model,
and then exposed to the view by Rails. The problem is that Rails
converts hashes assigned to views into HashWithIndifferentAccess, which
do not treat Symbols and Strings indifferently when comparing complete
hashes, even though they let you access the keys indifferently. in
Katrina’s case, this would pass:

assigns(:summary)[:total].should eq(139)
assigns(:summary)[:submitted].should eq(97)
assigns(:summary)[:published].should eq(82)
assigns(:summary)[:removed].should eq(12)

Make sense?

On Sun, Oct 24, 2010 at 3:51 AM, David C. [email protected]
wrote:

The problem is that Rails converts hashes assigned to views into
HashWithIndifferentAccess, which do not treat Symbols and Strings indifferently
when comparing complete hashes, even though they let you access the keys
indifferently.

(snip)

Make sense?

Ah, sanity returns. Thanks :slight_smile: