I have code like this:
module Empiric
module_function
def gem_version(name)
Gem.loaded_specs[name].version
rescue NoMethodError
raise NoMethodError, "No gem loaded for #{name}"
end
end
This is designed to look for a loaded gem and give the version, if the gem is found. In my project, the Capybara gem, for example, will NOT be there, so this works:
Empiric.gem_version("capybara")
When I say it "works", I mean it raises the appropriate exception. I'm trying to create an RSpec test for that and I came up with this:
it "indicates if a dependent gem is not found" do
expect {
Empiric.get_version("capybara")
}.to raise_error NoMethodError
end
The test passes ... however, test coverage indicates my raise
portion is not being covered.
Yet, if I change the above test to instead say .not_to raise_error NoMethodError
, the test fails. As it should. Note I changed it to "not_to" instead of "to". So this shows me the test is, in fact, recognizing that an error was generated.
Does this have to do with the fact that I'm specifically rescuing the error? Because the rescue
line shows that it's covered in the test coverage report, but the raise
statement is not, even though I've verified that it does in fact occur.
In terms of trying to answer my own question, I did come across this (How to write down the rspec to test rescue block.?) but that solution didn't seem to work at all for me. I also looked at this (How do I test the rescue block of a method with rspec mocks 3.3), which also offers little in the way of help for me. Likewise for this (Rspec: testing a rescue) and this (Using RSpec how can I test the results of a rescue exception block) and this (Rspec: Test rescue block).
Just to be clear, I'm not operating in a Rails context. This is a standalone gem I'm writing.
expect { ... }.to raise_error NoMethodError, "No gem loaded for capybara"
. Maybe it's a bug in coverage reporter? – katafraktexpected NoMethodError with "No gem loaded for capybara", got #<NoMethodError: undefined method
get_version' for Empiric:Module>`. Which is definitely odd, since I can call that method outside of a test without issue and without adding the exception message, I don't get this error about the method not being found at all. The coverage tool I'm using is SimpleCov. – Jeff Nymanget_version
vsgem_version
;) – katafraktHash#fetch
and rescue KeyError or the safe operator.&
. – maxGem.loaded_specs.fetch(name).version
andrescue KeyError
or the safe operatorGem.loaded_specs.fetch(name).&version
and check for nil. – max