Fixtures in real life, part 1
![]() |
| If you came here looking for these kind of fixtures, good luck on the way out ;) |
This post is part of an ongoing feature about creating a social network in Rails.
There’s lots of posts around about Rails fixtures, with critiques ranging from “[they’re] great!”, “they hurt a little early, but shine with complexity”, all the way to “do not use fixtures”. Few topics split the Rails community more, the eternal Rspec vs Minitest debate comes to mind.
However, something that I’ve found lacking in most of these fixtures posts are insights of:
- how fixtures fare in a real life app,
- how do they coexist with factories and plain objects, and
- what growth strategies to follow that will help you out in the long run.
That’s what we’re about to tackle on this post.
I’m not here to tell you to use fixtures or not. However, if you’re intrigued about them, or are just starting out and want to see what’s in for the long run, read up!
Here’s some base fixtures inspired by the ones in the Ztory repo for the Piccy app. We’ve got users how have photos with comments, and user_devices (phone, tablet, browser) for customization and tracking.
First of all, a couple users:
# test/fixtures/users.yml
default:
email: [email protected]
encrypted_password: 123456
locale: :en
another:
email: [email protected]
encrypted_password: 678910
locale: :en
A user device for each of them. Using the same name for the fixtures makes it easy to mentally link fixtures and means less names to remember.
# test/fixtures/user_devices.yml
default:
user: default
arn: "arn:aws:sns:us-east-1:123456789012:piccy:02034b43-fefa-4e07-a5eb-3be56f8c54ce"
model: "iPhone 6"
another:
user: another
arn: "arn:aws:sns:us-east-1:987654321098:piccy:de305d54-75b4-431b-adb2-eb6b9e546013"
model: "Samgsung Galaxy S5"
Some photos. Here we have a public and a private one for the default user, and a public one for another user to test for visibility and such.
# test/fixtures/photos.yml
default:
user: default
description: "My first photo, be gentle pls"
uuid: "d7391f40-ab17-11e4-bcd8-0800200c9a66"
public: false
private:
user: another
description: "I was feeling kinda inspired"
uuid: "f1fc2a71-ab17-11e4-bcd8-0800200c9a66"
public: false
public:
user: another
description: "Dynamic entry!"
uuid: "35a6afa5-97df-4e12-82a6-9272b0bc6d2e"
public: true
Finally, some comments. Here we’re using some embedded ruby to make the comments appear in the correct order. Also having some fun with the descriptions ;D
# test/fixtures/comments.yml
default:
user: default
photo: default
text: "Love this pic."
public:
user: default
photo: public
text: "Next time, less filters though."
created_at: <%= Time.zone.now + 1.minute %>
another:
user: another
photo: public
text: "Filters rule, I know"
created_at: <%= Time.zone.now + 5.minutes %>
private:
user: another
photo: private
text: "Too many filters for the world to see"
Tip: Use the annotate_models gem to get a nice a comment summarizing the current schema of the fixture, it saves you a jump to the schema file to check the attributes of a model.
To get to this point, I added a couple fixtures for each model as I was creating them, taking advantage of the Rails generators to create the files and the first fixture. After that, adding or editing fixtures to support new features is just a matter of some light modifications or a little copy & paste.
Now, what does that enables us to do? Here’s the whole test for comment visibility, in less than 25 lines:
# test/controllers/comments_controller_test.rb
describe "comments in the user's photos" do
it 'responds sucessfully' do
get :show, { id: comments(:default).id }
assert_response :ok
end
end
describe "#show" do
describe "comments in another user's photos" do
context 'when the photo is public' do
it 'responds sucessfully' do
get :show, { id: comments(:public).id }
assert_response :ok
end
end
context 'when the photo is private' do
it 'responds not found' do
get :show, { id: comments(:private) }
assert_response :not_found
end
end
end
end
Simple, straightforward, and very performant, since all the data is created in bulk at the start of the test. Following the “tests as documentation” idea, reading the controller test and associated fixtures tells us what’s implemented already, and gives us a solid foundation to further extend it.
That’s it for today! Next post, We’ll see how to test photo permalinks, by migrating an existing test with factories, showing some quirks and advantages of fixtures. Questions or comments, type away below :)
