mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 13:09:18 +08:00
DEV: Use rspec mocks to properly verify a race condition
This is a small followup of https://github.com/discourse/discourse/pull/28124.
This commit is contained in:
parent
6f80ebfc41
commit
9e9d88f078
2
Gemfile
2
Gemfile
|
@ -158,6 +158,8 @@ group :test, :development do
|
||||||
|
|
||||||
gem "syntax_tree"
|
gem "syntax_tree"
|
||||||
gem "syntax_tree-disable_ternary"
|
gem "syntax_tree-disable_ternary"
|
||||||
|
|
||||||
|
gem "rspec-multi-mock"
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
|
|
@ -426,6 +426,8 @@ GEM
|
||||||
rspec-mocks (3.13.1)
|
rspec-mocks (3.13.1)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.13.0)
|
rspec-support (~> 3.13.0)
|
||||||
|
rspec-multi-mock (0.3.1)
|
||||||
|
rspec (>= 3.7.0)
|
||||||
rspec-rails (6.1.3)
|
rspec-rails (6.1.3)
|
||||||
actionpack (>= 6.1)
|
actionpack (>= 6.1)
|
||||||
activesupport (>= 6.1)
|
activesupport (>= 6.1)
|
||||||
|
@ -699,6 +701,7 @@ DEPENDENCIES
|
||||||
rrule
|
rrule
|
||||||
rspec
|
rspec
|
||||||
rspec-html-matchers
|
rspec-html-matchers
|
||||||
|
rspec-multi-mock
|
||||||
rspec-rails
|
rspec-rails
|
||||||
rss
|
rss
|
||||||
rswag-specs
|
rswag-specs
|
||||||
|
|
|
@ -122,14 +122,16 @@ RSpec.describe Cache do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "isn't prone to a race condition due to key expiring between GET calls" do
|
context "when there is a race condition due to key expiring between GET calls" do
|
||||||
key = cache.normalize_key("my_key")
|
before do
|
||||||
|
allow(Discourse.redis).to receive(:get).and_wrap_original do |original_method, *args|
|
||||||
|
original_method.call(*args).tap { Discourse.redis.del(*args) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# while this is not technically testing the race condition, it's
|
it "isn't prone to that race condition" do
|
||||||
# ensuring we're only calling redis.get once, which is a good enough proxy
|
expect(fetch_value).to eq("bob")
|
||||||
Discourse.redis.stubs(:get).with(key).returns(Marshal.dump("bob")).once
|
end
|
||||||
|
|
||||||
expect(fetch_value).to eq("bob")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -186,7 +186,18 @@ end
|
||||||
PER_SPEC_TIMEOUT_SECONDS = 45
|
PER_SPEC_TIMEOUT_SECONDS = 45
|
||||||
BROWSER_READ_TIMEOUT = 30
|
BROWSER_READ_TIMEOUT = 30
|
||||||
|
|
||||||
|
# To avoid erasing `any_instance` from Mocha
|
||||||
|
require "rspec/mocks/syntax"
|
||||||
|
RSpec::Mocks::Syntax.singleton_class.define_method(:enable_should) { |*| nil }
|
||||||
|
RSpec::Mocks::Syntax.singleton_class.define_method(:disable_should) { |*| nil }
|
||||||
|
|
||||||
|
RSpec::Mocks::ArgumentMatchers.remove_method(:hash_including) # We’re currently relying on the version from Webmock
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
config.expect_with :rspec do |c|
|
||||||
|
c.syntax = :expect
|
||||||
|
end
|
||||||
|
|
||||||
config.fail_fast = ENV["RSPEC_FAIL_FAST"] == "1"
|
config.fail_fast = ENV["RSPEC_FAIL_FAST"] == "1"
|
||||||
config.silence_filter_announcements = ENV["RSPEC_SILENCE_FILTER_ANNOUNCEMENTS"] == "1"
|
config.silence_filter_announcements = ENV["RSPEC_SILENCE_FILTER_ANNOUNCEMENTS"] == "1"
|
||||||
config.extend RedisSnapshotHelper
|
config.extend RedisSnapshotHelper
|
||||||
|
@ -206,10 +217,18 @@ RSpec.configure do |config|
|
||||||
config.include ServiceMatchers
|
config.include ServiceMatchers
|
||||||
config.include I18nHelpers
|
config.include I18nHelpers
|
||||||
|
|
||||||
config.mock_framework = :mocha
|
|
||||||
config.order = "random"
|
config.order = "random"
|
||||||
config.infer_spec_type_from_file_location!
|
config.infer_spec_type_from_file_location!
|
||||||
|
|
||||||
|
config.mock_with :rspec do |mocks|
|
||||||
|
mocks.verify_partial_doubles = true
|
||||||
|
mocks.verify_doubled_constant_names = true
|
||||||
|
mocks.syntax = :expect
|
||||||
|
end
|
||||||
|
config.mock_with MultiMock::Adapter.for(:mocha, :rspec)
|
||||||
|
|
||||||
|
config.include Mocha::API
|
||||||
|
|
||||||
if ENV["GITHUB_ACTIONS"]
|
if ENV["GITHUB_ACTIONS"]
|
||||||
# Enable color output in GitHub Actions
|
# Enable color output in GitHub Actions
|
||||||
# This eventually will be `config.color_mode = :on` in RSpec 4?
|
# This eventually will be `config.color_mode = :on` in RSpec 4?
|
||||||
|
|
Loading…
Reference in New Issue
Block a user