How can I test a method's parameter?
def create_person child
end
Above code is my method. It takes a parameter named "child". I try to test this parameter. So, if method doesn't take parameter, test will give me error. I use minitest and Ruby on Rails.
You can use assert_raises to test if an ArgumentError is raised
assert_raises ArgumentError do
YourClass.create_person
end
Related
I need to ensure that running an importer results in sending out an email.
This is what I got so far:
describe '#import' do
it 'triggers the correct mailer and action', :vcr do
expect(OrderMailer).to receive(:delivery_confirmation).with(order)
Importer.new(#file).import
remove_backed_up_file
end
end
It fails with:
pry(#<ActiveRecord::ConnectionAdapters::TransactionManager>)> error
=> #<NoMethodError: undefined method `deliver_now' for nil:NilClass>
Which obviously can't work out as I am expecting the Mailer class to receive the (instance) method call. But how can I get a hold of the mailer instance that will receive the call? How would you test that a unit's method triggers a certain mailer?
I assume the delivery_confirmation method in reality returns a Mail object. The problem is that ActionMailer will call the deliver method of the mail object. You've set an expectation stubbing out the delivery_confirmation method but you haven't specified what should be the return value. Try this
mail_mock = double(deliver: true)
# or mail_mock = double(deliver_now: true)
expect(mail_mock).to receive(:deliver)
# or expect(mail_mock).to receive(:deliver_now)
allow(OrderMailer).to receive(:delivery_confirmation).with(order).and_return(mail_mock)
# the rest of your test code
If I got you right,
expect_any_instance_of(OrderMailer).to receive(:delivery_confirmation).with(order)
will test the mailer instance that will receive the call.
For more precision you may want to set up your test with the particular instance of OrderMailer (let's say order_mailer) and write your expectation the following way
expect(order_mailer).to receive(:delivery_confirmation).with(order)
I'm trying to write a test for my Message model. This model has a method 'send_message':
def send_message
ContactMailer.contact_mail(self.name, self.email, self.text, self.ip).deliver
end
In my rspec file I have the following:
mailer = double(ContactMailer)
mailer.should_receive(:contact_mail)
FactoryGirl.build(:message).send_message
I am receiving the following error:
Failure/Error: mailer.should_receive(:contact_mail)
(Double ContactMailer).contact_mail(any args)
expected: 1 time with any arguments
received: 0 times with any arguments
Any idea? Could it be because I'm not taking .deliver into account?
No, the issue is that you haven't told RSpec that ContactMailer should receive that message. The argument to double is just a way to "name" the double for documentation purposes, as discussed in https://github.com/rspec/rspec-mocks
You actually don't need a double in this case, as you can set the expectation directly on the ContactMailer class as follows:
ContactMailer.should_receive(:contact_mail)
I want to test this method in my controller.
def fetch_match_displayed_count(params)
match_count = 0
params.each do |param|
match_count += 1 if param[1]["result"] && param[1]["result"] != "result"
end
match_count
end
This is the test I've written so far.
describe "fetch_match_displayed_count" do
it "should assign match_count with correct number of matches" do
params = {"result_1"=>{"match_id"=>"975", "result"=>"not_match"}, "result_2"=>{"match_id"=>"976", "result"=>"match"}, "result_3"=>{"match_id"=>"977", "result"=>"not_sure"}, "result_4"=>{"match_id"=>"978", "result"=>"match"}, "result_5"=>{"match_id"=>"979", "result"=>"not_match"}, "workerId"=>"123", "hitId"=>"", "assignmentId"=>"", "controller"=>"mt_results", "action"=>"create"}
controller.should_receive(:fetch_match_displayed_count).with(params)
get :fetch_match_displayed_count, {params:params}
assigns(:match_count).should == 5
end
end
My problem seems to lie in this line get :fetch_match_displayed_count, {params:params}
The method is expecting params, but is getting nil.
I have two questions.
Should this method be in a helper and not in the controller itself (per Rails convention)?
How do I submit a get request and pass params in my test?
As a general rule, you should test the public interface of your class. For a controller, this means you test actions, not helper methods.
You should be able to make this work by setting up one or more separate test cases that call the appropriate action(s), then use a message expectation to test that the helper method is called with the right arguments -- or test that the helper method does what it is supposed to do (sets the right instance variables/redirects/etc).
I have a helper that accesses request.fullpath. Within an isolated helper test, request is not available. What should I do? Can I somehow mock it or something like that?
I'm using the newest versions of Rails and RSpec. Here's what my helper looks like:
def item(*args, &block)
# some code
if request.fullpath == 'some-path'
# do some stuff
end
end
So the problematic code line is #4 where the helper needs access to the request object which isn't available in the helper spec.
Thanks a lot for help.
Yes, you can mock the request. I had a whole long answer here describing how to do that, but in fact that's not necessarily what you want.
Just call your helper method on the helper object in your example. Like so:
describe "#item" do
it "does whatever" do
helper.item.should ...
end
end
That will give you access to a test request object. If you need to specify a specific value for the request path, you can do so like this:
before :each do
helper.request.path = 'some-path'
end
Actually, for completeness, let me include my original answer, since depending on what you're trying to do it might still be helpful.
Here's how you can mock the request:
request = mock('request')
controller.stub(:request).and_return request
You can add stub methods to the returned request similarly
request.stub(:method).and_return return_value
And alternative syntax to mock & stub all in one line:
request = mock('request', :method => return_value)
Rspec will complain if your mock receives messages that you didn't stub. If there's other stuff Just call your request helper method on the helper object is doing that you don't care about in your test, you can shut rspec up by making the mock a "null object",example. like Like so
request = mock('request').as_null_object
It looks like all you probably need to get your specific test passing is this:
describe "#item" do
let(:request){ mock('request', :fullpath => 'some-path') }
before :each do
controller.stub(:request).and_return request
end
it "does whatever"
end
In a helper spec, you can access the request using controller.request (so controller.request.stub(:fullpath) { "whatever" } should work)
The following generates an error: "undefined local variable or method `params'"
assert_equal params[:recipient_id], users(:one).id
How do you test the params hash?
Also, how do you test assert_redirect when there are params present? The params are appended to the URL, so testing for model_path or similar fails.
Working with built in test class in Rails 3.
http://guides.rubyonrails.org/testing.html#functional-tests-for-your-controllers gives some of this information.
In this case, params is attached to the #request or #response object (depending on what HTTP method you are testing), so you can refer to it as #request.params[:recipient_id].
For redirect:
assert_redirected_to post_path(assigns(:post)) will assert that you are redirected to the proper path for a given model. The assigns method should have the instance variables you are setting inside of the controller to pass to the view