Skip to content

Instantly share code, notes, and snippets.

@suchov
Created April 12, 2017 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save suchov/0b96f5753ba5dbbdf42efe2cfdabf61c to your computer and use it in GitHub Desktop.
Save suchov/0b96f5753ba5dbbdf42efe2cfdabf61c to your computer and use it in GitHub Desktop.
Testing Implementation Details
One metric of a solid test suite is that you shouldn’t have to modify your tests when
refactoring production code. If your tests know too much about the implementation
of your code, your production and test code will be highly coupled, and even
minor changes in your production code will require reciprocal changes in the test
suite. When you find yourself refactoring your test suite alongside a refactoring
of your production code, it’s likely you’ve tested too many implementation details
of your code. At this point, your tests have begun to slow rather than assist in
refactoring.
The solution to this problem is to favor testing behavior over implementation.
You should test what your code does, not how it does it.
class Numeric
def negative?
self < 0
end
end
def absolute_value(number)
if number.negative?
-number
else
number
end
end
# this is bad
describe "#absolute_value" do
it "checks if the number is negative" do
number = 5
allow(number).to receive(:negative?)
absolute_value(number)
expect(number).to have_received(:negative?)
end
end
# this is right
describe "#absolute_value" do
it "returns the number's distance from zero" do
expect(absolute_value(4)).to eq 4
expect(absolute_value(0)).to eq 0
expect(absolute_value(-2)).to eq 2
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment