Reputation: 15954
I'm writing a script that will be run using rails runner
on production to make some one-time changes to our database. I want to be sure that the script works as expected before we run it, so I'm writing RSpec tests to verify its behavior while I write it.
How can I invoke the script in my test examples? The script isn't a class or a module, so there aren't individual functions for me to test. Instead, the entire script will be loaded once, run from top to bottom, and then exited. I'm not sure how to invoke that from within an RSpec test.
I'm looking for something like:
describe "my script" do
it "should create the correct record" do
before_count = Orders.count
rails runner my_script.rb # What goes here?
expect(Orders.count).to eq(before_count + 1)
end
end
Upvotes: 1
Views: 1915
Reputation: 11
I would move the logic from the script into its own class. Then you can invoke the class in your script and in your tests or even when you're in the rails console. I've been using this pattern for a while and its pretty useful.
Upvotes: 1
Reputation: 683
We can help you with this, but this:
I'm writing a script that will be run using rails runner on production to make some one-time changes to our database.
Is what migrations are for. One time changes like this to the db should be done in a migration. This circumvents the need for rspec, as any changes like this should be reversible, as migrations should be.
Upvotes: 0
Reputation: 218
I think you want to use system:
system('rails runner my_script.rb')
edit #1
If you are willing to butcher the script, you can move the active components of your script into separate module and require
that:
# my_script.rb
require './lib/my_script.rb'
MyScript.call()
# lib/my_script.rb
module MyScript
def self.call
# your code
end
end
Then, in test:
require './lib/my_script.rb'
describe "my script" do
it "should create the correct record" do
before_count = Orders.count
MyScript.call() # here
expect(Orders.count).to eq(before_count + 1)
end
end
Upvotes: 0
Reputation: 15954
It looks like I can use Kernel#load
to execute the script:
describe "my script" do
it "should create the correct record" do
before_count = Orders.count
load(Rails.root.join("path", "to", "my-script.rb")
expect(Orders.count).to eq(before_count + 1)
end
end
Upvotes: 0