How to check if a method exists using Rspec? - ruby-on-rails

I want to write a nice clean check whether a method exists or not:
expect(subscriber.respond_to?(:fake_method)).to be(true) <-- This fails (as expected)
expect(subscriber).respond_to?(:fake_method) <-- This passes, why?
The fake_method does not exist, but when I use the second convention, my test passes.
Any ideas?

I believe I have the answer. The second convention doesn't work because the matcher is different according to the documentation:
https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/respond-to-matcher
You should try with:
expect(subscriber).to respond_to(:fake_method)
Cheers!

we can simply use expect(subscriber).not_to respond_to(:fake_method) for negative case.

Related

Is it possible to mark a test as pending in MiniTest?

And if this is possible, what is the syntax for this?
It took me a few minutes poking around on the RubyDocs to figure out the actual syntax for pulling this off. Figured I'd toss it here to save some future person a few clicks.
From inside your test, simply call the skip() method, like so:
skip("reason for skipping the test")
The method is MiniTest::Assertions#skip - http://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-skip
I figured this out. With minitest you don't mark tests as pending. But you can skip them:
http://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-skip
Also, when using MiniTest::Spec, if you don't pass a block to it(), the test is marked as skipped.

How to mock Rails::configuration

I'm attempting to test a class which makes use of the rails configuration file. I'd like to mock Rails::configuration.
I've tried things like
Rails::singleton_class.expects(:configuration).returns('result')
Rails::singleton_class.stubs(:configuration).returns('result')
How do I go about doing this?
Rails.expects(:configuration).returns('result')
Please note there was a typo in your example. The returned value must be passed using returns, not return.
Also note, Rails.configuration returns Rails.application.config. If your method doesn't use Rails.configuration directly, it might actually bypass the call and your expectation won't work.
Rails.stubs(:configuration).returns(Rails::Application::Configuration.allocate)
This answer on mocking a Net response
helped

In Ruby on Rails, is there a way to say, try Product.find(12345) but don't error if not found?

For example, just have it return nil if not found,
or must we always use begin... rescue... end to catch the exception?
You can use
Product.find_by_id(12345)
. This would return nil and not error.
Thanks....
You can use rescue_from to specify a method to use to handle the exception. If it's something that's used in multiple places this will help remove duplication. You could even put it in your application controller if it's used across controllers. Here are some examples: http://m.onkey.org/rescue-from-dispatching
You could test it first with Product.exists?(12345)

ruby on rails - dealing with variables not being set or not existing

I was wondering if there is a better way to check if a variable exists, currently I do this
if !params['attribute']['institution'].blank?
But if attribute doesn't exist then a error is thrown.
I saw .try() but couldn't see how it would work in this situation.
You can use present? or presence which was recently described by a blog post by Ola Bini.
if params['attribute'] && params['attribute']['institution']
Not the prettiest, but works.
You can use if params['attribute'].has_key? 'institution'

How to DRY up a ruby conditional structure needed for Rails

I'm finding I often have to use a structure to avoid a Rails error of undefined method 'name' for nil:NilClass.
The structure looks like this:
if country.state
country.state.name
end
It seems like a classic case of repeating oneself with country.state appearing twice in one simple block. Is there any way to DRY this up?
Rails adds a try method to object that mimics object#send but does not raise an exception if the object returns nil.
I think the syntax is
country.try(:state).name
Well not really. One option is to install the andand gem, but introducing a dependency for this may be a little much.
Other than using the slightly more concise syntax of:
country.state.name unless country.state.nil?
I don't think there's a DRY way to do this with the information given. I would argue that if you can't be sure whether country.state is nil or not, you may want to look at the code responsible for setting that value and determine whether that's a normal case or whether a validator upstream should be catching that.

Resources