Skip to content

Instantly share code, notes, and snippets.

@cupakromer
Last active August 29, 2015 13:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cupakromer/9980762 to your computer and use it in GitHub Desktop.
Save cupakromer/9980762 to your computer and use it in GitHub Desktop.
RSpec asserting on ActiveSupport deprecations

It seems that assert_deprecated is only part of ActiveSupport. So it is not part of rspec-expectations. It would probably only be added to rspec-rails but a quick google search did not turn up many uses of assert_deprecated.

I saw no past issues logged for RSpec regarding assert_deprecated so you are welcome to log it and argue your case for it. Though I see it being only part of ActiveSupport providing some barriers to adding it into rspec-expectations.

Now it should be fairly easy to roll your own matcher as well. There are two general approaches you could take:

  1. Method expectation

With this approach you treat ActiveSupport::Deprecation as a collaborator. Setting expectations on any messages you pass to it:

def deprecated_method
  ActiveSupport::Deprecation.warn('this has been removed', caller)
end

describe 'Expecting a specific deprecation' do

  it "checks the collaborator message" do
    allow(ActiveSupport::Deprecation).to receive(:warn)

    deprecated_method

    expect(ActiveSupport::Deprecation).to have_received(:warn)
      .with('this has been removed', anything)
  end

end
  1. Wrap assert_deprecated

If you really wanted to mimic all the extra work done by assert_deprecated but not re-write that behavior. You can do something like the following:

RSpec::Matchers.define :have_deprecated do |deprecation_match|
  include ActiveSupport::Testing::Deprecation

  # If using RSpec 3 this should be: match do |action_proc|
  match_for_should do |action_proc|
    has_deprecation?(deprecation_match, &action_proc)
  end

  # If using RSpec 3 this should be: match_when_negated do |action_proc|
  match_for_should_not do |action_proc|
    !deprecation_match && !has_deprecation?(nil, &action_proc)
  end

  def has_deprecation?(deprecation_match, &action_proc)
    @deprecations = assert_deprecated deprecation_match, &action_proc
    true
  rescue MiniTest::Assertion => @rescued_exception
    false
  end

  # If using RSpec 3 this should be: failure_message do
  failure_message_for_should do
    @rescued_exception.message
  end

  # If using RSpec 3 this should be: failure_message_when_negated do
  failure_message_for_should_not do
    if deprecation_match
      "Specifying a match for not raising a deprecation is not supported."
    else
      "expected no deprecation but received: #@deprecations"
    end
  end
end


def deprecated_method
  ActiveSupport::Deprecation.warn('this has been removed', caller)
end

describe 'Expecting a specific deprecation' do

  it "checks for a specific deprecation" do
    expect{ deprecated_method }.to have_deprecated 'this has been removed'
  end

  it "fails with non-matching deprecation" do
    expect{
      expect{ deprecated_method }.to have_deprecated 'bad message'
    }.to raise_error
  end

  it "checks for no deprecations" do
    expect{ :noop }.not_to have_deprecated
  end

  it "fails when a deprecation was received but not expected" do
    expect{
      expect{ deprecated_method }.not_to have_deprecated
    }.to raise_error
  end

  it "fails given a deprecation match when no deprecation is expected" do
    expect{
      expect{ deprecated_method }.not_to have_deprecated 'this has been removed'
    }.to raise_error
  end

end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment