Controller Hash → JSON → RSpec Test
| Step | Controller Code Example | JSON Output | RSpec Expectation json = JSON.parse(response.body) (*) json = JSON.parse(response.body, symbolize_names: true) |
|---|---|---|---|
| 1. Symbol keys | render json: { status: :ok, code: 200 } |
{'status':'ok','code':200} |
expect(json['status']).to eq('ok') |
| 2. String keys | render json: { 'status' => 'ok', 'code' => 200 } |
{'status':'ok','code':200} |
expect(json['status']).to eq('ok') |
| 3. Symbolized test | render json: { status: :ok } |
{'status':'ok'} |
expect(json[:status]).to eq('ok') |
| 4. Array of hashes | render json: { 'consoles' => [{ name: 'NES' }, { name: 'SNES' }] } |
{'consoles':[{'name':'NES'},{'name':'SNES'}]} |
expect(json['consoles'].map { _1['name'] }).to contain_exactly('NES','SNES')(note 1) |
| 5. Filtering | render(json: {'consoles' => consoles.map { |console| console[:name] } }) (note 2) |
{'consoles':[{'name':'NES'},{'name':'SNES'}]} |
expect(json['consoles']).to contain_exactly('NES','SNES','Wii') |
(note 1) Using Ruby 3 shorthand (_1) — both notations are equivalent:
expect(json['consoles'].map { _1['name'] }).to contain_exactly('NES','SNES')
expect(json['consoles'].map { |c| c['name'] }).to contain_exactly('NES','SNES')
(note 2) These controller lines are syntactically correct (string & symbol use):
render json: { 'consoles'=> [{ name: 'NES' }, { name: 'SNES' }] }
render json: { consoles: [{ name: 'NES' }, { name: 'SNES' }] }