I have a markdown helper that looks like this in application_helper.rb.
How would you go about writing a test for something like this? Also, is this the best way to generate simple HTML from markdown?
Thanks!
def markdown(text)
Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true).render(text).html_safe
end
Two options come to mind:
Stub out Redcarpet::Markdown and create an expectation of what it should receive:
expect(Redcarpet::Markdown).to receive(:new).with(...) # `with` args omitted for brevity
markdown(text)
The problem here is that the coupling between the method and the test is very high. It's very difficult to refactor the method without breaking the test, even though the method actually functions the same.
Assert the correctness of the output text directly:
expect(markdown(text)).to eq 'This is markdownified'
This allows you to refactor better, but it seems more like an integration test, not a unit test, and is almost testing Redcarpet more than your own method. Unit tests should usually assume that the external methods they call work correctly.
This is one of those cases where testing feels redundant to me since the method is just a thin wrapper around another, and I would not be against not unit testing it, and rather ensuring that you have an integration test—if this is by having your spec be an integration test, then that's probably okay.
It's ultimately all up to you and your TDD workflow and overall testing principles though.
Related
We have a RoR application, Rspec for tests with Webmock for HTTP requests.
After having to do some refactoring in our legacy codebase, I realized that many of our tests had unnecessary stubs.
Like this example, the do_a function has been refactored so that we don't do any api call so the stub_request is not necessary anymore, worse, it should be removed.
it 'does something' do
stub_request(:get, 'http://something.com/users/123')
do_a
expect(..)
end
One way of fixing this is:
it 'does something' do
stub_something = stub_request(:get, 'http://something.com/users/123')
do_a
expect(..)
expect(stub_something).to have_been_requested.once
end
But I'd like to enforce this directly through a strict mode where the test fails if any declared stub has not been called ? The first example would then fail automatically.
Thanks a lot for your help
You want to use expectations instead of stub_request:
expect(WebMock).to have_requested(:get, "http://something.com/users/123").once
# or
expect(a_request(:get, "http://something.com/users/123")).to have_been_made.once
But I'd like to enforce this directly through a strict mode where the test fails if any declared stub has not been called?
I don't think this is really possible unless you do some heavy monkeypatching - and it seems like a bad idea instead of just refactoring your tests.
I was wondering if there is a script that can take existing codebase and generate unit tests for each method in controllers. By default all would be passing since they would be empty and i can remove tests i for methods i dont feel important.
This would save huge time and increase testing. Since i'd have to define only what each method should output and not boilerplate that needs to be written.
You really shouldn't be doing this. Creating pointless tests is technical debt that you don't want. Take some time, go through each controller and write a test (or preferably a few) for each method. You'll thank yourself in the long run.
You can then also use test coverage tools to see which bits still need testing.
You can use shared tests to avoid repetition. So for example with rspec, you could add the following to your spec_helper/rails_helper
def should_be_ok(action)
it "should respond with ok" do
get action.to_sym
expect(response).to be_success
end
end
Then in your controller_spec
describe UserController do
should_be_ok(:index)
should_be_ok(:new)
end
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 one of my projects I need to collaborate with several backend systems. Some of them somewhat lacks in documentation, and partly therefore I have some test code that interact with some test servers just to see everything works as expected. However, accessing these servers is quite slow, and therefore I do not want to run these tests every time I run my test suite.
My question is how to deal with a situation where you want to skip certain tests. Currently I use an environment variable 'BACKEND_TEST' and a conditional statement which checks if the variable is set for each test I would like to skip. But sometimes I would like to skip all tests in a test file without having to add an extra row to the beginning of each test.
The tests which have to interact with the test servers are not many, as I use flexmock in other situations. However, you can't mock yourself away from reality.
As you can see from this question's title, I'm using Test::Unit. Additionally, if it makes any difference, the project is a Rails project.
The features referred to in the previous answer include the omit() method and omit_if()
def test_omission
omit('Reason')
# Not reached here
end
And
def test_omission
omit_if("".empty?)
# Not reached here
end
From: http://test-unit.rubyforge.org/test-unit/en/Test/Unit/TestCaseOmissionSupport.html#omit-instance_method
New Features Of Test Unit 2.x suggests that test-unit 2.x (the gem version, not the ruby 1.8 standard library) allows you to omit tests.
I was confused by the following, which still raises an error to the console:
def test_omission
omit('Reason')
# Not reached here
end
You can avoid that by wrapping the code to skip in a block passed to omit:
def test_omission
omit 'Reason' do
# Not reached here
end
end
That actually skips the test as expected, and outputs "Omission: Test Reason" to the console. It's unfortunate that you have to indent existing code to make this work, and I'd be happy to learn of a better way to do it, but this works.
This seems like a simple question but I can't find the answer anywhere. I've noticed that in general, tests in a Ruby on Rails app can be written as:
test "the truth" do
assert true
end
or
def the_truth
assert true
end
It seems newer material writes tests the first way, but I can't seem to find a reason for this. Is one favored over the other? Is one more correct? Thanks.
There has been a shift in recent years from short, abbreviated test names to longer, sentence-like test names. This is partly due to the popularity of RSpec and the concept that tests are specs and should be descriptive.
If you prefer descriptive test names, I highly recommend going with the test method. I find it to be more readable.
test "should not be able to login with invalid password" do
#...
end
def_should_not_be_able_to_login_with_invalid_password
#...
end
Also, because the description is a string it can contain any characters. With def you are limited in which characters you can use.
I believe the first method was implemented starting with Rails 2.2.
As far as I am aware, it simply improves readability of your code (as def can be any function while test is used only in test cases).
Good luck!
As Mike Trpcic suggests you should check out RSpec and Cucumber. I'd like to add that you should also take a look at:
Shoulda (http://github.com/thoughtbot/shoulda/tree/master)
Factory Girl (http://github.com/thoughtbot/factory_girl/tree/master)
Shoulda is a macro framework for writing concise unit tests for your models/controllers, while the second is a replacement for fixtures.
I would suggest doing your testing with either RSpec or Cucumber. I use both to test all my applications. RSpec is used to test the models and controllers, and Cucumber tests the Views (via the included Webrat functionality).