Goal

You’ll be able to write basic RSpec tests for a Rails model, and understand why testing the actual behavior matters more than testing implementation details.

Learn

RSpec is the most widely used testing framework in the Rails community, built around describing expected behavior in readable language:

RSpec.describe Product, type: :model do
  it "is invalid without a name" do
    product = Product.new(name: nil)
    expect(product).not_to be_valid
  end

  it "calculates the correct discounted price" do
    product = Product.new(price: 100)
    expect(product.discounted_price(10)).to eq(90)
  end
end

describe groups related tests around a specific class or feature; it defines one specific test case, described in genuinely readable, plain language explaining what’s actually being verified. expect(...).to makes an assertion about the actual behavior — this connects directly to the assert-based testing concept from earlier courses, just with more readable, structured syntax.

A genuinely important testing principle: test the actual observable behavior of your code (does a discount calculate correctly? is an invalid record correctly rejected?), not internal implementation details that could change without actually breaking anything meaningful. Tests tightly coupled to internal implementation details tend to break every time you refactor internal code, even when the actual external behavior stays completely correct — creating maintenance burden without genuine safety benefit.

Running rspec from the terminal executes your test suite, reporting exactly which tests passed and which failed, with genuinely readable descriptions pointing directly at what specifically went wrong.

Decision Task

You write a test that checks a private internal variable’s exact value inside a method, rather than checking the method’s actual returned result or observable effect. Before reading on: what real problem does this create the next time you refactor that method’s internal implementation, even if its external behavior stays correct?

Show Answer

The test would likely break purely because of the internal implementation change, even though the method’s actual external behavior (what it returns, what effect it has) remained completely correct. This creates genuine maintenance burden without real safety benefit — the test isn’t actually protecting against meaningful bugs, just detecting that internal code changed at all, which is a much weaker, less useful signal.

Common Mistake

Writing tests tightly coupled to internal implementation details rather than the actual observable behavior a method or class is supposed to provide. This kind of test breaks on every internal refactor, even when nothing genuinely wrong occurred, training developers to distrust or ignore test failures rather than treating them as meaningful signals.

Practice Questions

1. Write an RSpec test checking that a Product is invalid if its price is negative.

Show Answer

it "is invalid with a negative price" do\n product = Product.new(price: -10)\n expect(product).not_to be_valid\nend

2. What does describe do in an RSpec test file?

Show Answer

Groups related tests together around a specific class or feature.

3. What does expect(…).to actually do?

Show Answer

Makes an assertion about the actual behavior being tested, similar in concept to an assert statement, but with more readable structured syntax.

4. True or False: it’s generally good practice to test a method’s exact internal implementation details rather than its actual observable behavior.

Show Answer

False — testing observable behavior is generally more valuable and more maintainable than testing internal implementation details that could change without actually breaking anything meaningful.

5. What command runs an RSpec test suite from the terminal?

Show Answer

rspec

Try It Yourself

Without looking back, write an RSpec test verifying that a User model is valid when given a proper name and email.

Show Answer

it "is valid with a name and email" do\n user = User.new(name: "Ahmed", email: "ahmed@example.com")\n expect(user).to be_valid\nend

Quick Check

1. What is RSpec?

Show Answer

The most widely used testing framework in the Rails community.

2. What does describe group together?

Show Answer

Related tests around a specific class or feature.

3. What does it define?

Show Answer

One specific test case, described in readable language.

4. Should tests focus on observable behavior or internal implementation details?

Show Answer

Observable behavior — implementation-detail-focused tests tend to break unnecessarily on refactors.

5. What command runs the test suite?

Show Answer

rspec

تحميل هذا الباب / Download this Chapterنسخة كاملة للدراسة بدون إنترنت، مع الأسئلة والإجابات والصور المتاحة.