Is it possible to mark a test as pending in MiniTest? - ruby-on-rails

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.

Related

How do I expect a method to be run with specific ActiveRecord parameters

Using Mocha on Rails 4.2.
I'm testing a method that it should make a call to another method with the correct parameters. These parameters are ActiveRecord objects that it calls up from the database. Here is the key line in my test:
UserMailer.expects(:prompt_champion).with(users(:emma), [[language, 31.days.ago]]).once
Both users(:emma) and language are ActiveRecord objects.
Even though the correct call is made, the test fails because the parameters don't match the expectations. I think this might be because it's a different Ruby object each time a record is pulled up from the database.
I think one way around it is to see what method is being used in my code to pull up the records and stub that method to return mocks, but I don't want to do this because a whole bunch of Records are retrieved then filtered down to get to the right one, mocking all those records would make the test way too complex.
Is there a better way of doing this?
You could use block form of allow/expect.
expect(UserMailer).to receive(:prompt_champion) do |user, date|
expect(user.name).to eq "Emma"
expect(date).to eq 31.days.ago # or whatever
end
Sergio gave the best answer and I accepted it. I discovered the answer independently and found out along the way that I needed to return a mock from the ActionMailer method to make everything work properly.
I think it best to post here my complete test here for the sake of any other hapless adventurer to come this way. I'm using Minitest-Spec.
it 'prompts champions when there have been no edits for over a month' do
language.updated_at = 31.days.ago
language.champion = users(:emma)
language.save
mail = mock()
mail.stubs(:deliver_now).returns(true)
UserMailer.expects(:prompt_champion).with do |user, languages|
_(user.id).must_equal language.champion_id
_(languages.first.first.id).must_equal language.id
end.once.returns(mail)
Language.prompt_champions
end
You could use an RSpec custom matcher and compare expected values in that function.

How to check if a method exists using Rspec?

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.

Mocha Rails Weirdness

I'm seeing a very weird output from my Rails tests, using Mocha and Rails 3.1.0.
not all expectations were satisfied
unsatisfied expectations:
- expected exactly once, not yet invoked: #<GitAccess:0xbb5c344>.branches(any_parameters)
satisfied expectations:
- allowed any number of times, invoked once: #<GitAccess:0xbb5c344>.branches(any_parameters)
It says that my "branches" method was never called, but called once - on the same object? How is this possible? My controller looks like this:
def create
git_access.branches()
end
I'm totally not understanding how this is possible.
Okay, here's the answer. I somehow thought that .expects would only check whether the function is called or not. So in my test I had .expects and .stubs on the same function call, which made mocha ignore my .stubs.
By reading a bunch of tutorials online, .stubs should be used when you want to fake the response of a method, and .expects when you want to fake the response of a method AND test whether the method is called.

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

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