You [Gerald Bauer¹] have been permanently banned [for life] from participating in r/ruby (because of your writing off / outside of r/ruby). I do not see your participation adding anything to this [ruby] community.
-- Richard Schneeman (r/ruby mod and fanatic illiberal ultra leftie on a cancel culture mission)
¹: I know. Who cares? Who is this Gerald Bauer anyway. A random nobody for sure. It just happens that I am the admin among other things of Planet Ruby.
Case Studies of Code of Conduct "Cancel Culture" Out-Of-Control Power Abuse - Ruby - A Call for Tolerance On Ruby-Talk Results In Ban On Reddit RubyUpdate (August, 2022) - A Call for More Tolerance And Call For No-Ban Policy Results In Ban On Ruby-Talk (With No Reason Given)
> I just banned gerald.bauer@gmail.com. > > -- SHIBATA Hiroshi > >> THANK YOU >> >> -- Ryan Davis >> >> >> My full support to moderators. >> >> -- Xavier Noria >> >> My full support to moderators. >> >> -- Carlo E. Prelz >> >> That's fun. >> >> -- Alice
« 25 Days of Ruby Gems - Ruby Advent Calendar 2020, December 1st - December 25th
Written by Jason Swett
Blogs about Ruby on Rails Testing, speaks at international conferences and hosts the Rails with Jason Podcast.
factory_bot
is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.
There are three steps I go through to set up Factory Bot in a Rails application.
factory_bot_rails
gemrails_helper.rb
fileThe first thing I do is to include the factory_bot_rails gem (not the factory_bot
gem) in my Gemfile
. I include it under the :development, :test
group.
Here’s a sample Gemfile from a project with only the default gems plus a few that I added for testing.
Remember that after you add a gem to your Gemfile
you’ll need to run bundle install
in order to actually install the gem.
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.7.0'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.2', '>= 6.0.2.2'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'devise'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false
group :development, :test do
gem 'pry'
gem 'rspec-rails'
gem 'capybara'
gem 'webdrivers'
gem 'factory_bot_rails'
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background...
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
Factory definitions are kind of the “templates” that are used for generating new objects.
For example, I have a user object that needs an email and a password, then I would create a factory definition saying “hey, make me a user with an email and password”. The actual code might look like this:
FactoryBot.define do
factory :user do
email { 'test@example.com' }
password { 'password1' }
end
end
Factory Bot is smart enough to know that when I say factory :user do
, I’m talking about an Active Record class called User
.
There’s a problem with this way of defining my User
factory though. If I have a unique constraint on the users.email
column in the database (for example), then I won’t ever be able to generate more than one User
object. The first user’s email address will be test@example.com
(no problem so far) but then when I go to create a second user, its email address will also be test@example.com
, and if I have a unique constraint on users.email
, the creation of this second record will not be allowed.
We need a way of making it so the factories’ values can be unique. One way, which I’ve done before, is to append a random number to the end of the email address, e.g. "test#{SecureRandom.hex}@example.com"
. There’s a different way to do it, though, that I find nicer. That way is to use another gem called Faker.
The syntax for actually using a Factory Bot factory in a test is as follows:
FactoryBot.create(:user)
There’s nothing wrong with this, but I find that these FactoryBot
are so numerous in my test files that their presence feels a little noisy.
There’s a way to make it so that instead we can just write this:
create(:user)
The way to do that is to add a bit of code to spec/rails_helper.rb
.
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
(You don’t actually add the RSpec.configure do |config|
to the spec/rails_helper.rb
file. It’s already there. I’m just including it here to show that that’s the block inside of which the config.include FactoryBot::Syntax::Methods
line goes.)
Built with Ruby
(running Jekyll)
on 2023-01-25 18:05:39 +0000 in 0.371 seconds.
Hosted on GitHub Pages.
</> Source on GitHub.
(0) Dedicated to the public domain.