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

Failing rspec test when using stub_template with Rails 6.1 #2485

Open
glennakamura opened this issue Mar 16, 2021 · 3 comments
Open

Failing rspec test when using stub_template with Rails 6.1 #2485

glennakamura opened this issue Mar 16, 2021 · 3 comments

Comments

@glennakamura
Copy link

What Ruby, Rails and RSpec versions are you using?

Ruby version: 3.0.0
Rails version: 6.1.3
RSpec version: 3.10

  • rspec-core 3.10.1
  • rspec-expectations 3.10.1
  • rspec-mocks 3.10.2
  • rspec-rails 5.0.0
  • rspec-support 3.10.2

Observed behaviour

Tests using a previously stubbed template fail if another test clears the view cache.

$ bundle exec rspec
..F

Failures:

  1) stub.html.erb renders stub again
     Failure/Error: render
     
     ActionView::Template::Error:
       undefined method `__stub_html_erb___2739773391792524586_14880' for #<ActionView::Base:0x00000000007620>
     # ./spec/views/stub.html.erb_spec.rb:21:in `block (2 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # NoMethodError:
     #   undefined method `__stub_html_erb___2739773391792524586_14880' for #<ActionView::Base:0x00000000007620>
     #   ./spec/views/stub.html.erb_spec.rb:21:in `block (2 levels) in <top (required)>'

Finished in 0.05772 seconds (files took 0.69206 seconds to load)
3 examples, 1 failure

Failed examples:

rspec ./spec/views/stub.html.erb_spec.rb:20 # stub.html.erb renders stub again

Expected behaviour

All tests pass. (works with Rails 6.0)

Can you provide an example app?

Example app: https://github.com/glennakamura/rspec_stub_template_failure.git
Expect bundle exec rspec to pass but fails with Rails 6.1

@glennakamura
Copy link
Author

glennakamura commented Mar 16, 2021

Previously in Rails 6.0, ActionView::FixtureResolver did not cache templates but in Rails 6.1 the implementation was refactored to reuse more of ActionView::OptimizedFileSystemResolver which enabled caching. Rspec caches it own ActionView::FixtureResolver objects but the clear_cache method doesn't get called like the other resolvers when the view cache is cleared using ActionView::LookupContext::DetailsKey.clear. All of the view context objects containing the compiled methods are cleared but rspec now returns stale stub_template objects cached by ActionView::FixtureResolver.

      # ActionView::LookupContext::DetailsKey.clear
      def self.clear
        ActionView::ViewPaths.all_view_paths.each do |path_set|
          path_set.each(&:clear_cache)
        end
        ActionView::LookupContext.fallbacks.each(&:clear_cache)
        @view_context_class = nil
        @details_keys.clear
        @digest_cache.clear
      end

The commit in rails actionview that changes ActionView::FixtureResolver behavior:
rails/rails@c3c1c32#diff-d61cbf6aceb30d4858710c3b091dff28d6aac3732af8c73ca6e58de51f2c68bf

@glennakamura
Copy link
Author

FYI, I'm using the following workaround to get tests to pass until a proper fix is released:

RSpec.configure do |config|
  config.before :context, type: :view do
    RSpec::Rails::ViewExampleGroup::StubResolverCache
      .instance_variable_get(:@resolvers)
      &.each_value(&:clear_cache)
  end
end

@benoittgt
Copy link
Member

Thanks a lot @glennakamura for the detailed report. Would you like to make a patch?

I think we should clear cache in the after hook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants