Jake Worth

Hard-Code Your Expectations

Published: January 25, 2022 2 min read

Here’s an assertion I see in tests:

expect(user.full_name).to \
  eq("#{user.first_name} #{user.last_name}")

I push back against code like this because I think that hard-coded expectations are almost always better.

Hard-Coded Expectations

So, what is a hard-coded expectation? It’s an assertion about behavior that is just written out. Here’s an example:

expect(user.full_name).to eq("Jake Worth")

Why is this preferable? I think it’s preferable because we’re testing behavior rather than implementation, and we’ve written a more readable test.

Testing Behavior

"#{user.first_name} #{user.last_name}" exposes the implementation of full_name. That implementation can change.

Imagine we decided to read a new field on the model called display_name that happens to have a different value from the concatenated names. This test would start inexplicably failing, even though the user behavior is correct.

Asserting about the string directly ensures that the result is correct, without knowing anything about how correct is determined. The result is what matters.

Readability

One of main audiences of code is programmers, and “Jake Worth” is a string that I can simply read. I don’t have to know about anything else.

This creates a test suite that teaches me what the user experience is, rather than how a developer in the past chose to execute something.

Counterargument!

So, why do folks write tests this way? I think the idea is that these tests are easy to write because I don’t need know about my test data. My challenge would be: hard-code that too. Say what the setup is, say what the behavior ought to be. Let the test tell one coherent story.

Even if I can permit that point, there’s a real tradeoff: the test can be passing with a variety of bad assertions.

Imagine that first_name and last_name are nil for your test user, because you didn’t implement constraints on those fields like a meticulous database programmer. The original test passes because " " does, in fact, equal " ".

This is bad green, because a database with nil values in test will also have them in production, and some then customers to your website will be greeted with “Welcome !”, “Welcome Jake !”, or “Welcome Worth!”

✉️ Get better at programming by learning with me. Subscribe to Jake Worth's Newsletter for bi-weekly ideas, creations, and curated resources from across the world of programming. Join me today!


Blog of Jake Worth, software engineer in Maine.

© 2022 Jake Worth.