Ruby Test::Unit
имеет assert_nothing_raised
. Test::Unit
был заменен на MiniTest. Почему утверждения MiniTest/ожидания не имеют ничего подобного? Например, вы можете ожидать must_raise
, но не wont_raise
.
Почему у MiniTest:: Spec нет утверждения wont_raise?
Ответ 1
MiniTest реализует assert_nothing_raised
на своем уровне совместимости с Test:: Unit, но в своих собственных тестах (MiniTest::Unit
и MiniTest::Spec
) он не выполняет никаких подобных тестов. Причина в том, что программист утверждает, что тестирование для ничего поднятого не является чем-либо тестированием; вы никогда не ожидаете, что что-либо будет поднято в тесте, за исключением случаев, когда вы тестируете исключение. Если в коде для теста возникает непредвиденное (неперехваченное) исключение, вы получите сообщение об ошибке, указанное в хорошем порядке, и вы узнаете, что у вас есть проблема.
Пример:
require 'minitest/autorun'
describe "something" do
it "does something" do
Ooops
end
end
Вывод:
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
Это именно то, что вы хотели знать. Если бы вы ничего не ожидали, вы не получили его, и вам сказали, что это так.
Итак, аргумент здесь: не используйте assert_nothing_raised
! Это просто бессмысленный костыль. См. Например:
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
С другой стороны, ясно, что assert_nothing_raised
соответствует некоторой интуиции среди пользователей, так как многие люди ожидают, что wont_raise
отправится с must_raise
и т.д. В частности, хотелось бы сфокусировать утверждение на этом, а не просто тест. К счастью, MiniTest чрезвычайно минималистский и гибкий, поэтому, если вы хотите добавить свою собственную рутину, вы можете. Таким образом, вы можете написать метод, который проверяет отсутствие исключения и возвращает известный результат, если нет исключения, и теперь вы можете утверждать для этого известного результата.
Например (я не говорю, что это идеально, просто показывая идею):
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
Дело не в том, что это хорошая или плохая идея, но MiniTest никогда не отвечал за это.
Ответ 2
Если вам это нужно:
# test_helper.rb
module Minitest::Assertions
def assert_nothing_raised(*)
yield
end
end
И использовать его:
def test_unknown_setter
assert_nothing_raised do
result.some_silly_column_name = 'value'
end
end
Ответ 3
Это беспокоило меня достаточно, чтобы вникнуть в источники MiniTest и обеспечить реализацию в моем файле spec_helper.rb
:
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
Надеюсь, это окажется полезным для кого-то, кому также нужна wont_raise
. Ура!:)