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
Related
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.
I seem to only find SO posts asking how to assert that a method has no return value but what I want is to require that a method call in my tests never see any arguments passed to the method.
I expected to find some documentation in http://gofreerange.com/mocha/docs/Mocha/ParameterMatchers.html, but no luck ... should I be looking elsewhere?
The documentation for the with method doesn't appear to say this, but I discovered that calling with() with no parameters will force Mocha to check that the method call happens with no arguments.
Example:
MyClass.any_instance.stubs(:its_method).with.return true
Using MiniTest::Spec and Mocha:
describe "#devices" do
it "scopes the devices by the provided :ip_list" do
ips = 'fast tests ftw!'
ds = DeviceSearch.new ip_list: ips
Device.expects(:scope_by_ip_list).once.with(ips)
ds.devices
end
end
When I make the code work correctly, this test will fail, because calling Device.expects(:scope_by_ip_list) also stubs Device.scope_by_ip_list, and since I don't specify a .returns(Devices.scoped) or some such, it stubs out the method with nil. So, in my code which properly scopes a list of devices and then does further operations, the further operations blow up.
I don't want to have to specify a .returns parameter, though, because I totally don't care what it returns. I don't want to stub the method at all! I just want to set up an expectation on it, and leave it functioning just the way it is.
Is there a way to do that?
(To me, it seems very awkward to say something like Device.expects(:foo).returns('bar')—when I say that Model expects method, I'm not saying to stub that method! We can say Device.stubs(:foo), if we want to stub it.)
The behavior is intended and can't be changed. Look at the following post to see how it can be circumwented:
rspec 2: detect call to method but still have it perform its function
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.
I just started using mocha and I find it annoying that when creating a new mock object, mocha expects it to be called exactly once. I have helper methods to generate my mocks and I'm doing something like this
my_mock = mock(HashOfParameters)
All of the parameters might not get called for each test method so it will raise an error:
expected exactly once, not yet invoked
So I figured I needed to do something like this:
my_mock = mock()
HashOfParameters.each do |k, v|
my_mock.expects(k).returns(v).at_least(0)
end
This works but I was wondering if there was an easier way to do this, like changing a default configuration somewhere...
Ok, that was a stupid question... I hadn't took the time to truly understand the difference between a mock and a stub. Here's a good article that shows how it works :
http://martinfowler.com/articles/mocksArentStubs.html
So in my example, I should have been using the stub method instead of mock.