Do you see a test smell in the following code?
describe User do
let(:user) { FactoryGirl.create(:user, first_name: "John") }
describe "#full_name" do
it "returns the user's concatenated first and last name" do
expect(user.full_name).to(
eq("John Smith")
)
end
end
end
We've got a Mystery Guest on our hands!
The Mystery Guest smell is present when the reader of a test needs to look at information outside the test to understand the behavior being verified.
Our example actually exhibits this smell in two ways.
First, the it
block references a user
it did not create itself, relying instead on the let
to create the user. A reader must find the let
block to know what user
represents. This alone causes the Mystery Guest smell.
Further, this test relies on the fact that the user
has a default last name of "Smith." A reader would have to open the factories.rb
file to determine this. Even more smelliness.
By the way: Rails' fixtures are basically guaranteed to be Mystery Guests. This is also possible with factory_girl
as well, which is partly why we recommend making your factory definitions extremely simple, and overriding relevant attributes in your tests.
Here's how you might rewrite this test to remove the smells:
describe User do
describe "#full_name" do
it "returns the user's first and last name" do
user = FactoryGirl.create(
:user,
first_name: "John",
last_name: "Smith"
)
expect(user.full_name).to(
eq("John Smith")
)
end
end
end
Before we go, a quick note: the Mystery Guest is a code smell. A smell isn't necessarily a problem, it's just something that should make you take a closer look at your code. Sometimes removing a smell will make your code worse. Keep that in mind for all the following flashcards!
You can read more about the Mystery Guest on our blog.
You might also enjoy our Weekly Iteration episode on Rspec Best Practices.
Return to Flashcard Results