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: default@piccy.com encrypted_password: 123456 locale: :en
another: email: another@piccy.com 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 :)
