Skip to main content

Dealing with the deprecation on assert_equal nil in Minitest

In the midst of updating an app from Ruby 2.2.x to 4.2.1 I saw many variants on this message in my tests:

DEPRECATED: Use assert_nil if expecting nil from test/unit/proposals/proposal_test.rb:229. This will fail in Minitest 6.

This is a deprecation on assert_equal.

So I went off and read up on it.  I found some developers begging Zenspider to reverse the decision and his explanation that fixing tests may be a pain but it does uncover unsuspected bugs to actually notice when you are testing nil equals nil without necessarily knowing it. I've seen this happen in our own apps, so I get his point.

It is easy enough to fix the direct cases by just substituting the assert_nil for assert_equal nil. The cases where it is bothersome are the ones where you are iterating over a series of attributes or objects and some may be nil and some not and you just want to be sure they all match, nil or not.

So, to be ready for Minitest 6, after changing to assert_nil in the simple cases, I'm looking at converting those iterating cases from assert_equal to assert_equal_callout_nil and adding this to my test_helper  ActiveSupport::TestCase:

SILENCE_NIL_CALLOUTS = false 
def assert_equal_callout_nil to_match, under_test, *the_rest
  if to_match.nil?
    puts "#{caller[0]} called for testing nil equals nil, intended?" unless ((defined? SILENCE_NIL_CALLOUTS) && SILENCE_NIL_CALLOUTS)
    assert_nil under_test, *the_rest
  else    assert_equal to_match, under_test, *the_rest
  end 
end 
 

This will make tests work like before, and replace the deprecation warnings with messages like this that won't break in Minitest 6:

/Users/eaallen/projects/uam_ruby241/test/models/contacts/proposal_contact_test.rb:138:in `block (2 levels) in <class:ProposalContactTest>' called for testing nil equals nil, intended?

After changing test data to remove the nils where appropriate, the constant can be changed to silence the messages. Test runs should be made occasionally with it unsilenced to catch accidental nils. Unsilencing or starting with assert_equal when writing new tests will help avoid accidental nil vs nil.

Comments