Ruby's Test::Unit
has assert_nothing_raised
. Test::Unit
has been replaced by MiniTest. Why don't MiniTest's assertions / expectations have anything parallel to this? For example you can expect must_raise
but not wont_raise
.

- 3,526
- 1
- 33
- 47

- 515,959
- 87
- 875
- 1,141
3 Answers
MiniTest does implement assert_nothing_raised
in its Test::Unit compatibility layer, but in its own tests (MiniTest::Unit
and MiniTest::Spec
) it does not implement any test like this. The reason is, the programmer argues, that testing for nothing raised is not a test of anything; you never expect anything to be raised in a test, except when you are testing for an exception. If an unexpected (uncaught) exception occurs in the code for a test, you'll get an exception reported in good order by the test and you'll know you have a problem.
Example:
require 'minitest/autorun'
describe "something" do
it "does something" do
Ooops
end
end
Output:
Run options: --seed 41521
# Running tests:
E
Finished tests in 0.000729s, 1371.7421 tests/s, 0.0000 assertions/s.
1) Error:
test_0001_does_something(something):
NameError: uninitialized constant Ooops
untitled:5:in `block (2 levels) in <main>'
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
Which is exactly what you wanted to know. If you were expecting nothing to be raised, you didn't get it and you've been told so.
So, the argument here is: do not use assert_nothing_raised
! It's just a meaningless crutch. See, for example:
https://github.com/seattlerb/minitest/issues/70
https://github.com/seattlerb/minitest/issues/159
http://blog.zenspider.com/blog/2012/01/assert_nothing_tested.html
On the other hand, clearly assert_nothing_raised
corresponds to some intuition among users, since so many people expect a wont_raise
to go with must_raise
, etc. In particular one would like to focus an assertion on this, not merely a test. Luckily, MiniTest is extremely minimalist and flexible, so if you want to add your own routine, you can. So you can write a method that tests for no exception and returns a known outcome if there is no exception, and now you can assert for that known outcome.
For example (I'm not saying this is perfect, just showing the idea):
class TestMyRequire < MiniTest::Spec
def testForError # pass me a block and I'll tell you if it raised
yield
"ok"
rescue
$!
end
it "blends" do
testForError do
something_or_other
end.must_equal "ok"
end
end
The point is not that this is a good or bad idea but that it was never the responsibility of MiniTest to do it for you.

- 515,959
- 87
- 875
- 1,141
-
4Great answer. `assert_nothing_raised` is a noop. You are better off avoiding it. Love zenspider's comment from his blog post: "This is exactly why minitest doesn’t have `assert_nothing_raised`. You wind up with file after file of useless junk tests." – blowmage Sep 19 '12 at 17:13
-
1Suppose you wanted to verify that some JSON that you were generated was valid and would be parseable, I've seen code along the lines of assert_nothing_raised do JSON.parse(my_method_that_returns_some_json) end However I think that in the general case I agree with the above comments. – Dan Garland Feb 18 '14 at 15:50
-
1Do not name methods camelCase in ruby (testForError) but snake_case (test_for_error). But +1 for the answer: do not assert for nothing raised – Pascal Dec 19 '14 at 08:00
-
I need assert_nothing_raised, for example, when I have a method that raises an ArgumentError with a descriptive message for bad inputs, and want to ensure that there are no false positives (i.e. it doesn't raise an error on valid input). – Keith Bennett Jan 14 '15 at 21:47
-
@KeithBennett Me too. That's why my answer provides a way of doing exactly that. – matt Jan 14 '15 at 22:42
-
3While in strict sense it's all true, if you write a test without assertions, just to make sure the code doesn't throw an error, you'd probably add a comment saying "this shouldn't raise an error", so having an assertion seems more consistent, lest we ditch all of them, because `assert` is the only one you really need... `assert_false` -> use `!`; `assert_equal` -> use `==`; etc... it's all syntactic sugar. – Jul 14 '16 at 22:21
If you need it:
# test_helper.rb
module Minitest::Assertions
def assert_nothing_raised(*)
yield
end
end
And to use it:
def test_unknown_setter
assert_nothing_raised do
result.some_silly_column_name = 'value'
end
end

- 1,251
- 13
- 12
This bothered me enough to dig into the MiniTest sources and provide an implementation in my spec_helper.rb
file:
module MiniTest
module Assertions
def refute_raises *exp
msg = "#{exp.pop}.\n" if String === exp.last
begin
yield
rescue MiniTest::Skip => e
return e if exp.include? MiniTest::Skip
raise e
rescue Exception => e
exp = exp.first if exp.size == 1
flunk "unexpected exception raised: #{e}"
end
end
end
module Expectations
infect_an_assertion :refute_raises, :wont_raise
end
end
Hope this proves helpful to someone else who also needs wont_raise
. Cheers! :)

- 31
- 1