(Rails) PaperTrail and RSpec - ruby-on-rails

I'm having trouble with PaperTrail (auto-versioning of objects for Rails) being used with RSpec tests. Normally I want my tests to run without PaperTrail versioning, but there are a handful of tests for which I want PaperTrail turned on. I typically run my tests with Guard and Spork, and I can use things like PaperTrail.enabled = true and PaperTrail.enabled = false around a given test and everything works fine.
However, when I run the tests with RSpec, the tests requiring PaperTrail fail. To be more specific, it appears that while code in before filters can produce versions objects, code in the tests cannot. After a considerable amount of digging and tinkering and trying code snippets (I've tried this and this), it looks like the best solution is to use the require "paper_trail/frameworks/rspec" line mentioned in the PaperTrail README.
Unfortunately, each of these keeps me right where I started—tests pass with Guard/Spork but not vanilla RSpec. This is in particular an issue because while I use Spork locally, our continous integration server runs RSpec directly.
Does anyone have any insight?

PaperTrail now has documentation on tests with vanilla rspec
https://github.com/paper-trail-gem/paper_trail#7b-rspec
After including require 'paper_trail/frameworks/rspec' in your spec/rails_helpers.rb
... PaperTrail will be turned off for all tests by default. To enable PaperTrail for a test you can either wrap the test in a with_versioning block, or pass in versioning: true option to a spec block.

Somehow my issue was fixed by changing before(:all) and after(:all) behavior to before(:each) and after(:each).

Related

rails test database not clearing after some runs

I am using rspec to test and I notice that after running the tests, it sometimes leaves some records in the test database. I'm not sure why. I have use_transactional_fixtures set to true in my config file. But they don't go away until I manually delete the records. Does anyone have a way to stop this?
EDIT; before i said it was only when tests fail. that's no longer true.
I found the problem. Before(:all) blocks are not transactional
Try database_cleaner gem.
Truncation or Transaction strategy will work for you.
Caution: It can make your test suite run terribly slow.
Normally, proper use before, after in RSpec(if you are using it) works usually fine.

change your environment while running your tests cases

I have to change my rails environment while running my tests cases.
if Rails.env.production?
# Do something
else
# Do something else
end
How do i change my rails environment in mid of tests cases.
I am using rails 2.3.16 and ruby 1.9.3
If you want to test that code you need to stub that call by doing something like this.
Rails.stub_chain(:env, :production?).and_return(true)
That will basically make any call to Rails.env.production? return true.
You didn't give much of what framework you're using to run test cases so that works in RSpec with mocks.
That will make whatever call you're doing go in to that block of code so you can write tests against it.
To test the above mention code you can change your environment as mentioned by #Leo if you ar using RSpec.
If you are using Rails built in framework to write the test cases then You can do this.
Rails.env.stubs(:production?).returns(true)
Use
Rails.env.stubs(:production?).returns(true)
if you are using rails built-in testing framework for writing your test cases.
This question is better articulated like this (see below). I tried submitting these as edits to the original question but some "smart" reviewers decided to reject my edits. Interestingly, those who rejected my edits seem to have zero experience with ruby/rails
I have to write test cases for a piece of application code which is dependent on rails environment. The code reads like this:
if Rails.env.production?
# Do something
else
# Do something else
end
How do i simulate rails environment in my test cases so that I can test both the if part and else part of the logic?
I am using rails 2.3.16 and ruby 1.9.3

How do I get devise_async working with Cucumber?

I've followed the instructions for devise_async as per the README and I'm rolling Devise 2.1.2 and delayed_job. In my cucumber tests, I no longer receive the confirmation email as part of the sign-up process. Is there something I should be doing as part of testing? I already set delayed job to skip the actual delay for testing by setting the following in my test environment.
Delayed::Worker.delay_jobs = false
But even with this set to true, it still fails, albeit more slowly. If I remove the devise_async gem and the relevant lines, everything bursts back into life.
Thanks,
Graeme
The new version of devise-async triggers the emails after the record has been committed to the database. With RSpec, each test is wrapped in a transaction by default. Does Cucumber do the same? In that case you'll need to turn those test transactions off.
Here's what I use for RSpec:
http://www.denniskuczynski.com/2012/06/22/changing-individual-test-configuration-based-on-passed-in-options.html
you can turn off transactions in cucumber env
see how to use:
https://github.com/cucumber/cucumber/wiki/Browsers-and-Transactions
Did you try using the Delayed::Worker.new.work_off approach ?
Not sure it works for Devise async, but it worked for me previously for checking emails.
Using this step
Given /^Jobs are being dispatched$/ do
Delayed::Worker.new.work_off
end
And running this step before testing emails ?
In case you use devise-async with sidekiq, as some commenters here ask, the solution is to have tests run the workers inline:
require 'sidekiq/testing'
Sidekiq::Testing.inline!
See https://github.com/mperham/sidekiq/wiki/Testing

What testing tools and methods did Corey Haines use at GoGaRuCo 2011?

In this video from GoGaRuCo 2011, Corey Haines shows some techniques for making Rails test suites much faster. I would summarize it as follows:
Put as much of your code as possible outside the Rails app, into other modules and classes
Test those separately, without the overhead of loading up Rails
Use them from within your Rails app
There were a couple of things I didn't understand, though.
He alternates between running tests with rspec and spn or spna (for example, at about 3:50). Is spn a commonly-known tool?
In his tests for non-Rails classes and modules, he includes the module or class being tested, but I don't see him including anything like spec_helper. How does he have Rspec available?
Sorry about the confusion. spn and spna are aliases I have that add my non-rails code to rspec's load path. There isn't anything special about them, other than adding a -I path_to_code on the command-line.
These days, I add something like this to my .rspec file:
-I app/mercury_app
Then I can do simple require 'object_name' at the top of my specs.
As for not including spec_helper: that is true, I don't. When you execute your spec file with rspec <path_to_spec_file>, it gets interpreted, so you don't need to require rspec explicitly.
For my db specs these days, I also have built an active_record_spec_helper which requires active_record, establishes a connection to the test database, and sets up database_cleaner; this allows me to simply require my model at the top of my spec file. This way, I can test the AR code against the db without having to load up my whole app.
A client I am working at where we are using these techniques is interested in supporting some blog posts about this, so hopefully they will start coming out towards the middle of June.

How to unstub Mocha mock?

I have the following mocha mock that works great.
In a test.rb file:
setup do
Date.stubs(:today).returns(Date.new(2011, 7, 19))
Time.stubs(:now).returns(Time.new(2011,1,1,9,0))
end
The problem is that the timing is broken for the tests. After the tests run the date and time objects are still mocked.(!)
Finished in -21949774.01594216 seconds.
I added the following:
teardown do
Date.unstubs(:today)
Time.unstubs(:now)
end
This throws the following error for each test: WARNING: there is already a transaction in progress
Is this the proper way to unstub? Is it better to unstub at the end of the test file or even at the end of unit test suite?
Working in Rails 3.07 and Mocha 0.9.12
Thanks.
I don't know if this is fully your problem, but it is just unstub, not pluralized.
Other than that, there should be no issue. You definitely want to unstub after each test (or set of tests, if a bunch of tests need the stubbing) because once stubbed, it will stay stubbed, and that can screw up other tests.
The accepted answer is spreading misinformation and should be considered harmful.
One of the main purposes of a mocking library like Mocha is to provide automatic mock/stub teardown as part of the integration to various testing libraries. In fact if you look at the GitHub repo for Mocha you will see that significant maintenance effort is put into making Mocha work smoothly with all the versions of several different testing frameworks.
If this isn't working properly then you need to figure out why Mocha's built-in teardown isn't working. Unstubbing manually in your own teardown is just papering over the problem, and could hide subtler issues with stub leakage or Mocha otherwise misbehaving.
If I had to take a wild guess money would be on your stub somehow being run outside of an actual test because that's the most common cause I've seen for this kind of thing in the wild, but there's not enough information from the question to really ascertain.

Resources