Skip to content
New issue

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

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

Already on GitHub? # 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.

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

No branches or pull requests

2 participants