It requires a default link, which is fine, but a pain to test. Here’s how to write great tests regardless


Back in Rails v5, the venerable ‘belonging to’ theme got an important update: it started requiring a default link.
As Rails tells us, when we ran create!
, our user was searched by ID (500) in the database. Find out it doesn’t exist and prevent creation from going through by raising an error. Although this is not a strict guard like a foreign key constraint at the database level, it does give us reasonable protection from creating orphaned rows in our database.
I’m a big fan of Rchange it. Doing the wrong things must be hard. However, this belongs_to
The behavior applies in all environments including the test environment. For those of us who create database records in tests, that means we have to generate more data. Do you know what’s the biggest culprit in the slow test kits? Create Me!
Data generation is more harmful when our database is on another server. This, of course, is the most common continuous integration test setup for production grade applications. Every time we create a class, Rails fires a round trip to the database. Excursions usually take about 20-40 milliseconds. This isn’t terrible, but it definitely adds up when the same test needs to create several rows and you have hundreds of tests. The worst inconvenience is when you have a file belongs_to
Hierarchy:
- a
BillingAddress
Belongs toUser
- a
User
Belongs toUserGroup
- a
UserGroup
Belongs toCompany
Now when we go to write the most obvious test for a BillingAddress
Control looks like this:
Holy smoke! Our two-line test required four lines of setup and four round trips to the database! Since round trips to the database will dominate testing time when running in a continuous integration environment, it is not an exaggeration to say that belongs_to
Validation quadruples the test time.
Readers employed by a large company using Java will know one way out of this: with a dedicated effort, you can remove database queries (persistence layer) away from the object instantiation layer and then stop your persistent calls.
For the Rails crowd, it’s even easier: you can just patch a file find
And find_by
, or where
The method used in the console with a stub is to return some canned data. If you are using FactoryBot, this data will be provided by build
(who uses new
internally) instead of create
Thus avoiding the database altogether. skip create
This means that Rails will not play a file belongs_to
Check for ASC. It would look something like this:
Voila, there is no access to the database at all! It’s fast and not bad at typing. This is the the correct method (TM).
However, there are a variety of situations that we don’t talk about in a polite discussion but that we encounter. For example, this is an InTeGrAtIoN test, damn it! Or, your manager doesn’t believe in radicals because they pollute the natural order of things (and because they came from a java background). Or, your ex-coworker wrote all these horrible tests and you just need to make them better and not perfect. for you oh my acumen Programmer, I have a solution.
Wait no, don’t do that! While this example may (completely) be based on something we’ve already done (still do) at a company I (work for) it, that’s not the way to go! (Besides I swear, we fix!)
this is will Solve your problem you have to be able to create
The billing address is in your test but the cost is that you’ve lost the protection that association validation provides in production! What we really want is a way to allow validation to not run in our test environment. It would certainly be amplified if we didn’t define it as a parameter every time belongs_to
in our application. Fortunately, Rails provides:
Using this line in the configuration of your test environment, each file belongs_to
It will just skip validation in the test environment, allowing you to write brief and amazing tests like this:
While I am not going to prove that this is necessarily what you are Must You do, the truth is that it will get you really far. It is maintenance free, easy to use, and only requires access to a single database. And still keeps belongs_to
The validation you want in production (and even development) environments.
There is a counter-argument that your test environment should behave as much as a production environment as possible. This is correct. Reversing the development and production settings will alert you (by failure) when writing code Must Create an association but no. However, because You are a responsible programmer and because It is important that your code establishes this link, you should test it. If you don’t like risks, use a stub.
But for the rest of us who get a taste of a bit of wild riding off the rails, you’re welcome.