Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Key-based Import doesn't get stubbed #19

Open
mgpnd opened this issue Apr 12, 2020 · 5 comments
Open

Key-based Import doesn't get stubbed #19

mgpnd opened this issue Apr 12, 2020 · 5 comments
Labels
bug Something isn't working help wanted Extra attention is needed
Milestone

Comments

@mgpnd
Copy link

mgpnd commented Apr 12, 2020

Describe the bug

When a dependency is imported via key-based argument, stubbing doesn't affect it's resolving.

I've made a sample app that reproduces the issue: https://github.com/mgpnd/import_example

Here's the most important snippets from the app:

# Operation that will be imported and stubbed
module Example
  class Show
    def call
      self.class.name
    end
  end
end
class ExampleController < ApplicationController
  include ImportExample::Import[
    show_example: "example.show"
  ]

  def index
    @auto_imported = show_example.()
    @manually_resolved = ImportExample::Container["example.show"].()
  end
end

/spec/controllers/example_controler_spec.rb:

RSpec.describe ExampleController, type: :controller do
  describe '#index' do
    subject { get :index, params: { format: 'text/hmtl' } }

    ...
    
    before do
      # Stubbing is enabled somewhere else so this part works properly
      ImportExample::Container.stub('example.show', -> { 'operation stub' })
    end

    # Fails, @auto_imported == "Example::Show"
    it 'calls auto imported stub' do
      subject
      expect(assigns(:auto_imported)).to eq('operation stub')
    end

    # Passes, @manually_resolved == "operation stub"
    it 'calls manually resolved stub' do
      subject
      expect(assigns(:manually_resolved)).to eq('operation stub')
    end
  end
end

To Reproduce

  1. Define a dependency via auto_inject Import with key-based argument
  2. Stub the dependency in any test

Expected behavior

The dependency resolved to provided stub.

Your environment

  • Affects my production application: NO
  • Ruby version: 2.7

I've tried to reproduce the issue with plain dry-auto_inject and with basic dry-system, but it doesn't appear there, in both gems importing works properly so I'm reporting it here.

@mgpnd mgpnd added the bug Something isn't working label Apr 12, 2020
@solnic solnic added this to the 0.2.0 milestone Apr 14, 2020
@solnic
Copy link
Member

solnic commented Apr 14, 2020

Thank you for reporting this and especially for checking it in a plain dry-system setup. I'll look into this, it's very likely that test mode in Rails will require some special care :/

@dsalamau
Copy link

dsalamau commented Apr 14, 2020

Update

I'd like to add that when a dependency is imported via array import stubbing doesn't affect it's resolving too.

I've created a PR to this sample app that reproduces the key based args issue: https://github.com/mgpnd/import_example/pull/1/files

Please, take care about snippets below:

# Array import operation example
class ArrayImportExampleController < ApplicationController
  include ImportExample::Import[
    "example.show"
  ]

  def index
    @auto_imported = show.()
    @manually_resolved = ImportExample::Container["example.show"].()
  end
end
# Specs
require 'rails_helper'

RSpec.describe ArrayImportExampleController, type: :controller do
  describe '#index' do
    subject { get :index, params: { format: 'text/hmtl' } }

    it 'calls auto imported operation' do
      subject
      expect(assigns(:auto_imported)).to eq('Example::Show')
    end

    it 'calls manually resolved operation' do
      subject
      expect(assigns(:manually_resolved)).to eq('Example::Show')
    end

    context "when operations is stubbed" do
      before do
        ImportExample::Container.stub('example.show', -> { 'operation stub' })
      end

      it 'calls auto imported stub' do
        subject
        expect(assigns(:auto_imported)).to eq('operation stub')
      end

      it 'calls manually resolved stub' do
        subject
        expect(assigns(:manually_resolved)).to eq('operation stub')
      end
    end
  end
end
# Result
ArrayImportExampleController#index when operations is stubbed calls auto imported stub
     Failure/Error: expect(assigns(:auto_imported)).to eq('operation stub')
     
       expected: "operation stub"
            got: "Example::Show"

@solnic solnic modified the milestones: 0.2.0, 0.3.0 Jul 21, 2020
@stefanrendevski
Copy link

@dsalamau @mgpnd I was looking into this for my own project. I am not exactly certain where the problem is, but the following setup allows for correct stubs:

# spec/controllers/some_controller_spec.rb
RSpec.describe SomeController do
  before do
    setup_stubs
    @controller = described_class.new
  end

  let(:setup_stubs) do
    ImportExample::Container.stub('example.show', -> { 'operation stub' })
  end
end

This leads me to believe that an instance of a controller is created before the test setup in a spec is executed, and it is that instance that is used when you submit a request.

@solnic
Copy link
Member

solnic commented Sep 17, 2020

@stefanrendevski you definitely want to set up stubs in a before hook and the rspec integration (that we don't have yet) should make sure that container stubbing is setup/teared down in the right moment.

@ndan
Copy link

ndan commented Feb 4, 2021

It works for me in dry-system-rails, but not in dry-rails

@solnic solnic added the help wanted Extra attention is needed label Feb 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

5 participants