Minitest Cheat Sheet
Do you use Ruby (on and off Rails) and have objects holding data which you need store and retrieve later? Then Active Record might be the perfect tool for you!
Minitest do not come with any feature for testing requests, unlike request spec in RSpec. Fortunately, controller tests are able to test through everything in the backend like request tests if we don't mock anything. Here's how a controller test works. A Basic Controller Test. A basic controller test includes a HTTP verb and the response we expect. Google Cheat Sheet Three-Pack. Google Cheat Sheet Three-Pack. Regular price $17.99 Sale price $17.99 Regular price $20.97 Unit price / per. IN 30 MINUTES Books. Excel Basics In 30 Minutes: The beginner's guide to Microsoft Excel, Excel Online, and Google Sheets. Tig - cheat sheet. Tig is a user-friendly text-mode interface for git based on ncurses. Navigation shortcuts. Enter - open a detail view; k / j - move up / down on the list; home / end - jump to top / bottom on the list (fn - / fn. The best way start and advance with Minitest Popular Posts 4 Fantastic Ways to Set Up State in Minitest Code Quality: Metrics That Matter Minitest Cheat Sheet Stubbing External APIs with WebMock A Few Modest Best Practices for Git Dress Up Your Minitest Output. Minitest also provides an optional RSpec-like DSL, which is not covered here. Minitest is a small (some might say “mini”) testing framework, where tests are written in “plain Ruby,” as opposed to using a custom DSL. It has a gentler learning curve than RSpec, and is the default testing framework for Rails.
In this article I give you a short overview of Active Record and explain how to use it with a few examples which I found to be essential. I will also share some points I found to be quite difficult to get right.
Ruby’s Active Record is an Object-Relational-Mapping layer: ORM lets you store data in a relational database and interact with it as objects.
For example, instead of manually querying data using SQL statements and then converting it manually into an array, using Active Record’s User.all
returns an array already filled with the wanted data.
With the help of ORM’s it’s also possible to store and load data with complex relationships as objects, resolving the relationships to connections between objects.
Minitest Cheat Sheet Template
For a more in-depth overview of what an ORM is, I can recommend the video Introduction to Object-Relational Mapping.
If you are unfamiliar with relational databases, have a look at my previous Database Basics series.
Active Record and databases
Active Record (AR) handles the connection to the database. It’s a simple configuration:
We’re going to be using an in-memory SQLite3 database for the following examples. Please note that the content of your database will be lost after each script run. If you want the data to be persistent, you can replace the second to last line above with database: db/ar_basics.sqlite3
.1
I decided to write minitest snippets. minitest is a testing framework and allows us to easily declare our expectations of the the code written. This might be like shooting canons at sparrow but it is a nice tool to get familiar with easily.
Assuming you are familiar with RubyGems (a gem is packaged Ruby library) and already have gem
installed (otherwise look here), run this terminal command in your tutorial directory to install the minitest gem:
gem install minitest
Now we extend the above Ruby script set-up by two more lines
and save the file as helpers/activerecord_setup_helper.rb
so we can simply reference it in our tests.
Minitest Cheat Sheet
Going back to my very first example from Database Basics, Part 1, where we want to save data about Employees and their Departments.
Here is an example with inline explanations:
Minitest Cheat Sheet Printable
That’s a lot to take in at first glance but we’re looking at it step by step. The setup is done in a single file to provide a quick one-glance-overview, there are three parts to it:
ActiveRecord::Schema.define do
defines the co-called Active Record schema. The schema is essentially the description of your database structure. Two tables,employees
anddepartments
, are being created in the database. Each block defines that tables columns:- The first one describes the columns
department_name
anddepartment_head
and both only accept strings as valid data. - The second block describes
name
andcity
as string, andpostal_code
as integer.t.references :department
adds the foreign keydepartment_id
to the table (see Foreign key as a refresher). This serves as a relational reference to thedepartments
table.
- The first one describes the columns
- We have two model class definitions which tells AR how to handle the database relations as Ruby object.
- The class
Department
uses the keywordhas_many
to indicate that it’s a to many relation, so eachDepartment
entity can have zero to manyEmployees
. - The class
Employee
on the other hand indicates withbelongs_to
that eachEmployee
has exactly oneDepartment
it is related to.
- The class
- The third part of the script is the minitest part where we get to play with the just set up AR models.
- The
before
block is run once before the following test suite to set up the database entries that will be tested:- First we define an
Employee
instance calledEric
. - Then we create an instance of
Department
calledHospitation
and the head of his department is calledOlivia
. - With
eric.department = hospitation
we set the relation between EmployeeEric
and DepartmentHospitation
. Behind the scenes AR adds theid
of the rowHospitation
inDepartment
table toEric
’s row in thedepartment_id
column). - And since we changed the object
eric
, we need tosave!
it to the database again.
- First we define an
- Then we
describe
the context that the tests will run (which for us right now is more to put in words what is going to be tested).- In the first test (marked with minitest’s keyword
it
) we then query the database by using the methodwhere
of AR modelEmployee
to find the entry that has the nameEric
. And since.where
returns an array (even if there is only one result) we select thefirst
result. We then tell the test that we expect the object’s name to be indeedEric
. - Likewise, in the seconds test, we again query the first
Eric
entry to check if the name of the department he’s working in is indeedHospitation
.
- In the first test (marked with minitest’s keyword
- The
Only points 1 and 2 are needed to setup the AR magic. Note that the names of AR tables are always plural and lower case (employees
) while the model names are always singular and capitalized (Employee
). This is part of one of the guiding principles of Ruby on Rails, “convention over configuration.”
Now we can execute the script via ruby employee_department.rb
. You should see something like this:
We can see that both tables departments
and employees
are being created. The two .
indicate that two tests have run and since there are no failures listed, it worked exactly as expected.
Let’s change this example to have a bit more finesse and normalise it into the Third Normal Form!
The main difference here is t.references :department_head, foreign_key: { to_table: :employees }
in the schema. This adds a column called department_head
to the table which references the employees
table, alongside with belongs_to :department_head, class_name: 'Employee'
in the Department
model.
With these two changes we can then do the following: Department.create(department_name: 'Hospitation', department_head: @olivia)
. In the previous example, we were only able to save Olivia’s name as the department head’s value. Now we can reference the entity that represents Olivia’s entry. And as you can see in _(eric.department.department_head).must_equal @olivia
, the query returns an object with all the data of the original object @olivia
.
It took me some time to get unary relationships right in AR, so let’s have a look at that.
In this example we only have one model, Employee
. And an employee can have a supervisor, which is, of course, also an employee. Therefore the model references itself.
- The
Employees
table gets a column calledsupervisor_id
viat.references :supervisor
. - The definitions
belongs_to :supervisor, class_name: 'Employee'
in theEmployee
model states that an Employee has one supervisor which is of the same class. - An Employee can also have multiple Employee entities as supervisees:
has_many :supervisee, class_name: 'Employee', foreign_key: 'supervisor_id'
. The foreign key in this case is the one we defined usingbelongs_to
.
This relation is also called a “Self Referential” or “Self Join” in Active Record.2
When we then test if Olivia has two supervisees in the second test, that is correct. olivia.supervisee.pluck(:name)
returns an array with both employees’ names.3
The concept of an entity having other entities can sometimes be a bit confusing, especially when the entities are only “connected” through something else.
Like in the case of doctors and their patients: Although a doctor sees many patients, his only happens when the patient has an appointment with that doctor. So, both doctors and patients have many appointments, and only through those appointments a relation with one another is made:
As you can see, the models Doctor
and Patient
both have many :appointments
, while Appointment
belongs to the doctor
and patient
entities. By extend, that is to say through: :appointments
, a doctor has patients and a patient has doctors. The relation between the two is indirect.
- In the Doctor model we are saying that the doctor has many appointments and at the same time has many patients but only because s/he has appointments. A doctor can’t have any patients without there being an appointment to bring the them together.
- In the Appointment model we are saying that appointments only belong to a doctor and a patient. One appointment can only have one doctor and one patient at a time. One appointment can’t have many doctors or have many patients.
When querying the appointments Dr. Wellington Yueh has on the 17th of September, it will correctly return the one with Logan Five.
Active Record is a mighty tool for saving and querying related data entities. And there are many, many more ways to query than I haven’t touched upon. I suggest you have a look at the Ruby on Rails guides entries for Active Record basics and Active Record querying for further information about it.
Minitest Cheat Sheet Excel
Further readings:
Alex’s Rails Cheat Sheet for more about naming conventions.
Minitest Cheat Sheet Pdf
documentation on Active Record’s
establish_connection
↩a quick article on The power of Self -Referential Associations in Rails (and self-joins)↩
documentation on Active Record’s
pluck
↩