On Wednesday, 27 February 2019 16:05:18 UTC+1, belgoros wrote:
>
>
>
> On Wednesday, 27 February 2019 16:02:23 UTC+1, Jon Rowe wrote:
>>
>> You need to include your concern in your fake controller.
>>
>> We do have the anonymous controller helpers for this purpose. See: 
>> https://relishapp.com/rspec/rspec-rails/docs/controller-specs/anonymous-controller
>>
>> Although you’ll still need to include the concern.
>>
>
> Weird, I have it defined as follows without including the module Response 
> as it was included in ApplicationController:
>
> require 'rails_helper'
>
>
> class FakeController < ApplicationController
> end
>
>
> RSpec.describe FakeController, type: :controller do  
>   it_should_behave_like "JSON Responsive controller" do 
>     let(:instance) { FakeController.new }
>   end
>
> end 
>
>>
>> Cheers
>> Jon Rowe
>> ---------------------------
>> [email protected]
>> jonrowe.co.uk
>>
>> On 27 February 2019 at 13:25, belgoros wrote:
>>
>> On Wednesday, 27 February 2019 14:08:53 UTC+1, belgoros wrote:
>>
>>
>>
>> On Wednesday, 27 February 2019 12:02:12 UTC+1, Jon Rowe wrote:
>>
>> If you need a controller you need a controller spec, its not practical to 
>> instantiate a controller on your own, one of the many reasons why they are 
>> recommended against by the Rails team now.
>>
>> Otherwise you need to test the behaviour of the end result, e.g. create a 
>> set of shared examples for your concern and use them in every 
>> request/system/integration test for the routes concerned.
>>
>>
>> I tried it as follows:
>>
>> #spec/controllers/concerns/response_spec.rb
>> require 'rails_helper'
>> class FakeController < ApplicationController
>> end
>> RSpec.describe FakeController, type: :controller do
>>
>>   let
>> (:controller) { FakeController.new}
>>
>>   
>>   
>> FakeModel = Struct.new(:name)
>>
>>   describe 
>> 'Response concern' do
>>
>>     context 
>> '#json_response' do
>>
>>       it 
>> 'renders JSON response' do
>>
>>         fake_model 
>> = FakeModel.new('example')
>>
>>         result 
>> = controller.json_response(fake_model)
>>
>>         puts 
>> "result: #{result.inspect}"
>>        
>>       
>> end
>>
>>     
>> end
>>
>>     
>>   
>> end
>> end
>>
>> but it fails with:
>>
>> rspec spec/controllers/concerns/response_spec.rb 
>>
>> F
>>
>> Failures:
>>
>>   1) FakeController Response concern #json_response renders JSON response
>>
>>      Failure/Error: render response
>>
>>      
>>
>>      Module::DelegationError:
>>
>>        ActionController::Metal#status= delegated to @_response.status=, 
>> but @_response is nil: #<FakeController:0x00007fd004810700 @_routes=nil, 
>> @_request=nil, @_response=nil, @_config={}, @_db_runtime=109.12200000000001>
>>
>>      # ./app/controllers/concerns/response.rb:6:in `json_response'
>>
>>      # ./spec/controllers/concerns/response_spec.rb:14:in `block (4 
>> levels) in <top (required)>'
>>
>>      # ------------------
>>
>>      # --- Caused by: ---
>>
>>      # NoMethodError:
>>
>>      #   undefined method `status=' for nil:NilClass
>>
>>      #   ./app/controllers/concerns/response.rb:6:in `json_response'
>>
>> Finished in 0.17825 seconds (files took 1.12 seconds to load)
>>
>> 1 example, 1 failure
>>
>>
>> What am I missing here ?
>>
>>
>> I modified by creating a shared example as follows:
>>
>> #spec/shared/json_response.rb
>> require 'rails_helper'
>> RSpec.shared_examples 'JSON Responsive controller' do |controller_class|
>>
>>   let
>> (:controller_class) { including_class.new }
>>
>>
>>
>>   it 
>> 'render JSON response' do
>>
>>     expect
>> (controller_class).to respond_to(:json_response)
>>
>>   
>> end
>> end
>>
>>
>> Then by using it in a controller spec:
>> #spec/controllers/concerns/fake_controller_spec.rb
>> require 'rails_helper'
>> class FakeController < ApplicationController
>> end
>> RSpec.describe FakeController, type: :controller do
>>
>>   it_behaves_like 
>> 'JSON Responsive controller', FakeController
>> end
>>
>>
>> But it fails as follows:
>>
>> Failures:
>>
>>   1) FakeController behaves like JSON Responsive class render JSON 
>> response
>>
>>      Failure/Error: expect(controller_class).to respond_to(:json_response
>> )
>>
>>        expected FakeController to respond to :json_response
>>
>>      Shared Example Group: "JSON Responsive class" called from 
>> ./spec/controllers/concerns/fake_controller_spec.rb:7
>>
>>      # ./spec/shared/json_response.rb:7:in `block (2 levels) in <main>'
>>
>>
The error is due the call render response in Response module:
def json_response(object, status = :ok, opts = {})
    response = {json: object, status: status}.merge(opts)
    puts "++++++++ response: #{response.inspect}"
    render response
  end

The 'puts' displays:

++++++++ response: {:json=>#<Double :model>, :status=>:ok}

 
But the error says is related to Module::DelegationError:

Module::DelegationError: 

ActionController::Metal#status= delegated to @_response.status=, but 
@_response is nil: #<FakeController:0x00007faf08fe0920 @_routes=nil, 
@_request=nil, @_response=nil, @_config={}, @_db_runtime=181.55> 

Shared Example Group: "JSON Responsive controller" called from ./spec/
controllers/concerns/fake_controller_spec.rb:7 

# ./app/controllers/concerns/response.rb:7:in `json_response' 

# ./spec/shared/json_response.rb:13:in `block (3 levels) in <main>' 

# ------------------ 

# --- Caused by: --- 

# NoMethodError: 

# undefined method `status=' for nil:NilClass 

# ./app/controllers/concerns/response.rb:7:in `json_response'

 
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/fac66db8-a749-4fc7-9ad3-9706a6523e3c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to