Little factories
You’ve probably used Rails fixtures or factory_bot to set up an object for testing purposes. But this can be too much when you’re just testing a simple data object.
I like to reach for this little helper:
def build_user(**) = User.new(
name: "Joel",
email: "joel@example.com",
**
)
Here, we’ve defined a method build_user
, that takes keyword arguments (**
) and returns a new instance of User
with some defaults. Because we pass the keyword arguments down to the initializer, any given keyword argument will override the specified default keyword arguments.
Say we want a user with the name “Jill”, but for this test, we don’t care about the email address. We could call our little factory like this:
build_user(name: "Jill")
We’re taking advantage of two recently added Ruby features to make this so concise.
We’re using an endless method definition by using an `
=
` after the method signature.We’re using an anonymous keyword argument splat `**` to soak up and pass on the given keyword arguments.
Both of these features are available in the latest Ruby, version 3.2.2. If you’re using an older version of Ruby, the method can be written like this instead.
def build_user(**kwargs)
User.new(
name: "Joel",
email: "joel@example.com",
**kwargs
)
end
I like to use endless method definitions when the method consists of a single statement (not necessarily one line). It saves space and reduces indentation. I especially like it for methods that just enumerate assignments. This is a good example of that. Another example might be a method that returns a literal Hash.
def attributes = {
name: "Joel",
email: "joel@example.com"
}
I think the anonymous splat is a nice way to indicate that the splat is never used by this method; it’s only passed on. The same is true of anonymous blocks and anonymous positional argument splats `&
` and `*
`.