14

コントローラーで割り当てると

@my_hash = { :my_key => :my_value }

そして、そのコントローラーをテストします

get 'index'
assigns(:my_hash).should == { :my_key => :my_value }

次に、次のエラー メッセージが表示されます。

expected: {:my_key=>:my_value},
got: {"my_key"=>:my_value} (using ==)

シンボルから文字列への自動変換が行われるのはなぜですか? ハッシュのキーに影響するのはなぜですか?

4

6 に答える 6

8

「stringify_keys」を呼び出してみてください:

assigns(:my_hash).should == { :my_key => :my_value }.stringify_keys
于 2010-12-10T19:19:35.280 に答える
7

It may end up as a HashWithIndifferentAccess if Rails somehow gets ahold of it, and that uses string keys internally. You might want to verify the class is the same:

assert_equal Hash, assigns(:my_hash).class

Parameters are always processed as the indifferent access kind of hash so you can retrieve using either string or symbol. If you're assigning this to your params hash on the get or post call, or you might be getting converted.

Another thing you can do is freeze it and see if anyone attempts to modify it because that should throw an exception:

@my_hash = { :my_key => :my_value }.freeze
于 2010-12-03T18:08:17.583 に答える
1

あはは!これは、Rails 自体が原因ではなく、Rspec が原因で発生しています。

コントローラー仕様で aの値をテストするのと同じ問題がありHashie::Mashました (ただし、 a のように鳴るすべてのものに適用されますHash) 。

具体的には、コントローラー仕様でassignsは、コントローラー アクションで設定されたインスタンス変数にアクセスするために呼び出すと、設定したインスタンス変数が正確に返されるのではなく、Rspec が a のメンバーとして格納されている変数のコピーHashWithIndifferentAccess(すべてを含む)が返されます。割り当てられたインスタンス変数)。Hash残念ながら、 a (または から継承するものHash) を aに貼り付けるHashWithIndifferentAccessと、同じ非常に便利ですが、正確ではないクラスのインスタンスに自動的に変換されます:)

最も簡単な回避策は、「便宜上」変換される前に、変数に直接アクセスして変換を回避することですcontroller.view_assigns['variable_name']

したがって、元の投稿のテストは、次のように変更された場合に合格するはずです。

get 'index'
controller.view_assigns['my_hash'].should == { :my_key => :my_value }

(もちろん、.shouldRSpec の新しいバージョンではサポートされなくなりましたが、比較のためにそのままにしておきました)

詳細については、この記事を参照してください

于 2015-07-21T22:07:15.677 に答える
0

Hashオブジェクトを の初期化子に渡すこともできますHashWithIndifferentAccess

于 2011-08-08T23:02:00.227 に答える