In my RSpec controller test, I'm trying to test a particular action that makes a call to a subfunction. But I don't want the test to include the call to that subfunction. (it'll raise an error that simply cannot be fixed in my dev environment)
What's the best way to omit this subfunction call from this controller action while I'm running a test over it?
Thanks.
You can stub that subfunction call in the before block of your rspec test for that function like so
describe "test for the main_action"
before(:each) do
controller.stub!(:sub_action).returns(true)
end
end
Then none of your test examples would actually call this sub_action.
Just for semantics, Rspec always runs in test environment not in development but I gather what you mean.
Related
Very new to testing
I have a model-less rails app with a controller called "PokerController"
in poker_controller.rb, I have a private method that looks like this:
private
def test(x)
1 + x
end
Then I have a file called 'poker_controller_test.rb' in test/controllers
I'm trying to do something like this:
require 'test_helper'
class PokerControllerTest < ActionController::TestCase
test "check if test == 2" do
test = test(1)
assert test == 2
end
end
As you can see, I'm trying to save the result of the function 'test' being called, to a variable called 'test' then I'm checking to see if that == 2.
Basically, I'm trying to pass in a number (in this case '1') to the test method, and I want the test to add 1 to 1, and expect to get 2.
I'm sure I'm just not setting up the test right, but how do I call a custom method like this and then evaluate what's returned?
Here's my result from the error in the test:
Error:
PokerControllerTest#test_check_if_test_==_2:
ArgumentError: unknown command "\x01"
test/controllers/poker_controller_test.rb:6:in `test'
test/controllers/poker_controller_test.rb:6:in `block in <class:PokerControllerTest>'
You don't.
Testing private methods in general is frowned upon*.
In Rails you mainly test controllers through integration tests. These are tests that send real HTTP requests to your application and then you write assertions about the response or the side effects of sending the request.
"[...] You can test what cookies are set, what HTTP code is returned, how the view looks, or what mutations happened to the DB, but testing the innards of the controller is just not a good idea."
- David Heinemeier Hansson
An example of an integration test is:
require "test_helper"
class PokerControllerTest < ActionDispatch::IntegrationTest
test "can see the welcome page" do
get "/path/to/somewhere"
assert_select "h1", "Welcome to my awesome poker app"
end
end
If you have a method that you want to test in isolation it does not belong in your controller in the first place and arguably it should not be a private method either.
You should test the public API of your objects. The public API of a controller is the methods that respond to HTTP requests via the router.
The use of ActionController::TestCase is discouraged outside of legacy applications.
New Rails applications no longer generate functional style controller
tests and they should only be used for backward compatibility.
Integration style controller tests perform actual requests, whereas
functional style controller tests merely simulate a request. Besides,
integration tests are as fast as functional tests and provide lot of
helpers such as as, parsed_body for effective testing of controller
actions including even API endpoints.
Besides that the issues with your test is that you're calling the test method on the instance of ActionController::TestCase and not your controller. You're then shadowing the method by defining an instance variable with the same name which is rarely a good thing.
Even if you did call the method on the controller Ruby would still raise an error since you're calling a private method from outside the object - thats the whole point of private methods.
While you could violate encapsulation by calling #controller.send(:test) this is just a bad idea on so many levels.
I tried testing this method in rspec:
def resend_if_failed
ResendWorker.new(self).resend_message
end
How do I test that ResendWorker.new(self).resend_message gets executed?
If you have the instance in your spec, you can just do :
expect(instance).to receive(:resend_if_failed)
instance.resend_if_failed
Obviously I guess resend_if_failed is triggered by another method.
Then if necessary, test resend_if_failed behaviour in isolation.
worker = double
allow(ResendWorker).to receive(:new).and_return(worker)
expect(worker).to receive(:resend_message)
instance.resend_if_failed
I have a helper class, ApplicationHelper, that has a method, build_links(). I have another class, AppleClass, that refers to that method.
AppleClass
def foo
....
build_links
end
end
ApplicationHelperClass
def build_links
main_app.blah_path(1)
end
end
The complication here is that there's an Engine, so I usually explicitly reference "main_app.blah_path" not just "blah_path".
The test against foo passes by itself, in its file, and when I run all helpers. It fails, though, when I include it in all the unit tests - "rake spec:suite:unit", and with our entire suite. All Apple tests pass, all ApplicationHelper tests pass. The only failing ones are when one method is referring to the other method, in routes, outside of the engine, in the full suite.
`undefined local variable or method `main_app' for #
<RSpec::Core::ExampleGroup::Nested_45::Nested_1:0x007fc134b30130>`
My suspicion is that the test helper, or some config, is not loading the engine's routes early enough, and thus links to "main_app" don't make sense. If I remove main_app, the test fails until it's run in the main suite.
Does anyone have tips on troubleshooting what's really going on? Also, could I kickstart the routing somehow in test_helper?
ruby-1.9.3-p385, rails 3.2.13, rspec 2.13.0
I had the same issue and found that if I added this method to the top of my Controller RSpec test case, then it resolved the issue entirely.
def main_app
Rails.application.class.routes.url_helpers
end
I think this issue is related to this question
I'm using this sort of code in my code in my Unit tests.
test "should be awesome" do
assert true
end
I'm using FactoryGirl instead of fixtures.
I find that I'm repeating myself a lot and having helper functions would be quite useful. What's the best way to create and call a helper function in the unit test? Is there a before_filter available like it is in the controllers (I tried putting it in, but it's just an undefined method). Any help is appreciated!
You can add utility functions to your unit tests without a problem. As long as you don't call them name them like "test_something" they won't get run as unit tests. You can then call them from your actual unit test methods (the format you use boils down to having a method in the class anyway).
So:
test "should be awesome" do
assert_general_awesomeness
assert true
end
private
def assert_general_awesomeness
assert true
end
Utility methods that are going to be used all over the place can go in test_helper and they will be available to all your tests. You could alternatively have a module that you mix in to your tests to provide common utility methods.
If you are doing common calls to set up before a unit test you can put in in a setup method which will be called before each test in the class.
In a Rails application I have a Test::Unit functional test that's failing, but the output on the console isn't telling me much.
How can I view the request, the response, the flash, the session, the variables set, and so on?
Is there something like...
rake test specific_test_file --verbose
You can add puts statements to your test case as suggested, or add calls to Rails.logger.debug() to your application code and watch your log/development.log to trace through what's happening.
In your test you have access to a bunch of resources you can user to debug your test.
p #request
p #response
p #controller
p flash
p cookie
p session
Also, remember that your action should be as simple as possibile and all the specific action execution should be tested by single Unit test.
Functional test should be reserved to the the overall action execution.
What does it mean in practice? If something doesn't work in your action, and your action calls 3 Model methods, you should be able to easily isolate the problem just looking at the unit tests. If one (or more) unit test fails, then you know which method is the guilty.
If all the unit tests pass, then the problem is the action itself but it should be quite easy to debug since you already tested the methods separately.
in the failing test use p #request etc. its ugly, but it can work
An answer to a separate question suggested
rake test TESTOPTS=-v
The slick way is to use pry and pry-nav gems. Be sure to include them in your test gem group. I use them in the development group as well. The great thing about pry and pry nav is you can step through your code with a console, so you can not only see the code as it's executed, but you can also enter console commands during the test.
You just enter binding.pry in the places in the code you want to trigger the console. Then using the 'step' command, you can move line by line through the code as it's executed.