Comments (10)
Using Whenever gem, automate the to-do item deletion.
task delete_items: :environment do
Item.where("created_at <= ?", Time.now - 7.days).destroy_all
end
from blocitoff.
Time.now - 7.days
can also be written as 7.days.ago
from blocitoff.
So how do I TDD this? I could write the test in the model specs, but is that where it belongs? Do I create a new file to test the whenever gem? Is there a way to test against the whenever gem? I'm not finding anything easily.
from blocitoff.
Testing rake tasks is tricky. Testing passage of time is also tricky. And it seems you have both problems combined. :)
To test a rake task the best approach is to start with extracing the code into a module. You can put it in app/models
and name it like a command (e.g. DeleteItems
or DeleteItemsTask
). Then the rake code would look like something this:
task delete_items: :environment do
DeleteItems.run # or "call", or "execute"
end
Testing a module is trivial, you basically test it like any other model.
The second problem: testing passage of time was usually solved using the Timecop gem. But since Rails 4.1 there is now a travel_to testing helper. Use any of those to simulate passage of time in your test.
In the end, a basic test will have the following structure:
- Make some new todos.
- Travel in time 7 days into the future.
- Call the delete-items module.
- Assert that all todos were removed.
from blocitoff.
So let me make sure I'm understanding this correctly. I can leave my rake task in the lib
folder, but also create a app/models/DeleteTodos.rb
file, but somehow make this a module? So maybe:
module DeleteTodos
task delete_todos: :environment do
Todo.where("created_at <= 7 ?", 1.week.ago).destroy_all
end
end
Then just write a test in the todo model spec against running this module?
from blocitoff.
I found a few examples online, and thought about trying them. My tests are passing now, but you are my mentor so you can tell me if this is bad practice or something:
require 'rails_helper'
require 'rake'
describe Todo do
before do
@user = create(:user)
@todo = create(:todo, created_at: Time.new(2014, 7, 31, 9, 5, 0))
load "tasks/delete_todos.rake"
Rake::Task.define_task(:environment)
end
describe "#expiration_date" do
it "returns the number of days remaining before todo is deleted" do
expect(@todo.expiration_date).to eq(Time.new(2014, 8, 7, 9, 5, 0))
end
end
describe "#delete_completed_todo" do
it "deletes the todo after the todo is marked as complete" do
@todo.update_attribute("completed", true)
expect(Todo.count).to eq(0)
end
end
describe "#delele_todos" do
include ActiveSupport::Testing::TimeHelpers
it "deletes the todo after 7 days" do
travel_to Time.new(2014, 8, 7, 9, 5, 0) do
Rake::Task["delete_todos"].invoke
expect(Todo.count).to eq(0)
end
end
end
end
from blocitoff.
The model file should be named app/models/delete_todos.rb
. The convention is to use a camel case for the class names, but snake case for the file names.
Since the rake file is to look like this:
task delete_items: :environment do
DeleteTodos.run
end
the module file has to look like this:
module DeleteTodos
def self.run
Todo.where("created_at <= 7 ?", 1.week.ago).destroy_all
end
end
from blocitoff.
Loading rake tasks is possible, although I don't like it. I prefer making rake tasks so simple they can't be wrong and then testing the separate modules.
from blocitoff.
Cool:)
Now I understand! I read about it and hear about it, but it's still a foreign idea that people write their own classes and modules in Rails. Seems like Rails just has it all kinda built in for you, so you do not have to write extra things. I guess you have to write a lot of custom stuff in Sinatra!
from blocitoff.
Rails is just a framework, a scaffolding for your code. It does not release you from using good programming practices (like separating business logic into classes and modules in this case).
from blocitoff.
Related Issues (8)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blocitoff.