Say I have a Company which may contain many employees of type Employee may contain many tasks of type Task.
class Company < ActiveRecord::Base; has_many :employees; end
class Employee < ActiveRecord::Base; belongs_to :company, has_many :tasks; end
class Task < ActiveRecord::Base; belongs_to :employee; end
Using tools like FactoryGirl I may be tempted to create tasks using FactoryGirl.create(:task)
forcing an employee and a company to be created as well.
What I want to do is to create valid ActiveRecord objects but with their relationships stubbed out so as to make my tests faster.
A solution I came up is to not use FactoryGirl and create the new objects using mock_model/stub_model to stub their associations.
Example:
employee = mock_model(Employee)
task = Task.create! name: "Do that", employee: employee
Am I doing it right?
Thanks.
Whereas an instance of ActiveRecord::Relation is a representation of a query that can be run against your database (but wasn't run yet). Once you run that query by calling to_a , each , first etc. on that Relation a single instance or an array of ActiveRecord::Base instances will be returned.
ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.
ActiveRecord is commonly used with the Ruby-on-Rails framework but you can use it with Sinatra or without any web framework if desired.
What is ActiveRecord? ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.
If you don't want to create anything in the database you can do this:
employee = mock_model(Employee)
task = mock_model(Task, name: "Do that", employee: employee)
Keep in mind that you can't query them like that. It's roughly the same as building the object. If you ever want to do anything where you need to query actual data such as an integration test then you'll need use create
to make stuff in the database. Or as one commenter pointed out, you can use FactoryGirl's methods to stub stuff out.
There is a distinct difference between mock_model
and stub_model
.
Assuming you're using RSpec, check out Mock Model and Stub Model.
Briefly though, the main difference is that mock_model
is a true test double, that acts like an AR model. stub_model
will create an instance of an actual AR model.
Either one of these options, along with Eric C's code snippet, is a good way to isolate your tests from the DB.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With