rspec/rspec-core — pull request #1635 by dapplebeforedawn (2014-07-12 04:42:42+00:00)
Title: default lets to a uuid if no block given

This patch encourages correct specs by discouraging "magic strings".

A common pattern I see in specs is:

```ruby
let(:username) { "teh user" }
let(:email) { "an-email@example.com" }
let(:password) { "sekret" }
let(:description) { "our favorite user" }
```

Basically, the spec author is just filling in junk values to populate a
record. These junk values tend to become "magic strings" in the test:

```ruby
expect(user.email).to eq("an-email@example.com")
```

It's also unclear to the next developer reading the spec if there really
is something special about the values in the let, or if they are just
junk values.

Both of these problems can be solved by using UUIDs anywhere you'd use a
junk value:

```ruby
let(:email) { SecureRandom.uuid }
```

This has the added benefit of preventing a whole class of specification
errors: false positives caused by misunderstanding the state of the
system.

In a test with a shared resource, like a database, those magic values
may already exist in the database, making the example `expect`
above susceptible to false positives.

When using UUIDs for all junk values, you can be reasonable certain that
each let is globally unique, even in a shared resource. This also
allows them to be treated as quasi-primary keys:

```ruby
expect(User.find_by_description(description)).to be_present
```

Finally, it's really nice not having to think up the junk values.
Naming things is hard, even if you don't care about the name.

----
A consequence of the UUID technique is that you end up with lots of lets like:

```ruby
let(:username) { SecureRandom.uuid }
let(:email) { SecureRandom.uuid }
let(:password) { SecureRandom.uuid }
let(:description) { SecureRandom.uuid }
```

With this patch, this can be written as:

```ruby
let(:username)
let(:email)
let(:password)
let(:description)
```

----
The examples I used here are slated towards a Rails application, but
this technique is useful anytime you don't care about the value of the
let, which is almost always in my experience.

I realize I'm asking for a significant change to rspec's behavior. If I've been unclear in this pull request, please ask for clarification.