Bird
Raised Fist0
Rubyprogramming~10 mins

Mocking and stubbing in Ruby - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Mocking and stubbing
Start Test
↓
Create Stub
↓
Call Method
↓
Return Stubbed Value
↓
Create Mock
↓
Expect Method Call
↓
Verify Mock
↓
End Test
The test starts by creating stubs to replace methods with fixed returns, then mocks to expect calls, and finally verifies those expectations before ending.
Execution Sample
Ruby
class User
  def name; 'Alice'; end
end

user = User.new
allow(user).to receive(:name).and_return('Bob')
puts user.name
This code replaces the User's name method to always return 'Bob' instead of 'Alice'.
Execution Table
StepActionMethod CalledStub/Mock SetupReturn ValueOutput
1Create User instance----
2Stub 'name' method on usernameStub returns 'Bob'--
3Call 'name' method on username-BobBob
4End of test----
💡 Test ends after method call returns stubbed value 'Bob'
Variable Tracker
VariableStartAfter Stub SetupAfter Method CallFinal
user.nameAliceStubbed to 'Bob'Returns 'Bob'Bob
Key Moments - 2 Insights
Why does user.name return 'Bob' instead of 'Alice'?
Because in step 2 of the execution_table, the 'name' method is stubbed to always return 'Bob', overriding the original method.
What is the difference between a stub and a mock here?
A stub replaces a method to return a fixed value (step 2), while a mock would also check if the method was called as expected (not shown in this simple example).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the return value of user.name at step 3?
A'Alice'
B'Bob'
Cnil
DError
💡 Hint
Check the 'Return Value' column at step 3 in the execution_table.
At which step is the stub for the 'name' method created?
AStep 1
BStep 3
CStep 2
DStep 4
💡 Hint
Look at the 'Stub/Mock Setup' column to find when the stub is applied.
If we remove the stub setup in step 2, what would user.name return at step 3?
A'Alice'
Bnil
C'Bob'
DError
💡 Hint
Refer to variable_tracker for user.name initial value before stubbing.
Concept Snapshot
Mocking and stubbing in Ruby:
- Stub replaces a method to return fixed value.
- Mock sets expectations on method calls.
- Use 'allow(obj).to receive(:method).and_return(value)' for stubbing.
- Use 'expect(obj).to receive(:method)' for mocking.
- Verify mocks to ensure methods were called.
- Helps isolate tests from real dependencies.
Full Transcript
This visual trace shows how mocking and stubbing work in Ruby tests. First, a User object is created with a name method returning 'Alice'. Then, the name method is stubbed to return 'Bob' instead. When calling user.name, the stubbed value 'Bob' is returned instead of the original 'Alice'. This helps tests control method outputs. Mocks would also check if methods are called as expected, but this example focuses on stubbing. The variable tracker shows how user.name changes from 'Alice' to 'Bob' after stubbing. The key moments clarify why the stub changes the return value and the difference between mocks and stubs. The quiz questions help reinforce understanding by referencing the execution steps and variable states.

Practice

(1/5)
1. What is the main purpose of stubbing in Ruby testing?
easy
A. To check if a method was called with specific arguments
B. To slow down tests by adding delays
C. To run the actual method code during tests
D. To replace a method's return value with a fake one

Solution

  1. Step 1: Understand stubbing concept

    Stubbing means replacing a method's output with a fake value to control test behavior.
  2. Step 2: Differentiate from mocking

    Mocking checks method calls, but stubbing focuses on return values.
  3. Final Answer:

    To replace a method's return value with a fake one -> Option D
  4. Quick Check:

    Stubbing = fake return value [OK]
Hint: Stubs fake returns; mocks check calls [OK]
Common Mistakes:
  • Confusing stubs with mocks
  • Thinking stubs run real code
  • Believing stubs slow tests
2. Which of the following is the correct syntax to stub a method foo on an object obj to return 42 using RSpec?
easy
A. allow(obj).to receive(:foo).and_return(42)
B. expect(obj).to stub(:foo).and_return(42)
C. obj.stub(:foo).returns(42)
D. mock(obj).expects(:foo).returns(42)

Solution

  1. Step 1: Recall RSpec stubbing syntax

    In RSpec, stubbing uses allow(object).to receive(:method).and_return(value).
  2. Step 2: Check each option

    allow(obj).to receive(:foo).and_return(42) matches correct syntax; others use outdated or incorrect methods.
  3. Final Answer:

    allow(obj).to receive(:foo).and_return(42) -> Option A
  4. Quick Check:

    RSpec stub = allow + receive + and_return [OK]
Hint: Use allow(obj).to receive(:method).and_return(value) [OK]
Common Mistakes:
  • Using deprecated stub syntax
  • Confusing expect with allow for stubs
  • Using mock instead of allow for stubs
3. What will be the output of this Ruby code using RSpec mocks?
class Calculator
  def add(a, b)
    a + b
  end
end

calc = Calculator.new
allow(calc).to receive(:add).with(2, 3).and_return(10)
puts calc.add(2, 3)
puts calc.add(4, 5)
medium
A. 10 10
B. 10 9
C. 5 9
D. 5 5

Solution

  1. Step 1: Analyze stubbed method call

    The method add is stubbed to return 10 only when called with arguments 2 and 3.
  2. Step 2: Check calls and outputs

    First call calc.add(2, 3) returns 10 due to stub. Second call calc.add(4, 5) is not stubbed, so runs original method returning 9.
  3. Final Answer:

    10 9 -> Option B
  4. Quick Check:

    Stubbed args return 10; others run real method [OK]
Hint: Stub affects only specified arguments [OK]
Common Mistakes:
  • Assuming all calls return stub value
  • Ignoring method arguments in stub
  • Expecting syntax error
4. Identify the error in this RSpec mocking code:
user = double('User')
expect(user).to receive(:login).with('admin')
user.login('guest')
medium
A. Missing stub for login method
B. The double is not created correctly
C. The method login is called with wrong argument
D. No error, code is correct

Solution

  1. Step 1: Understand the expectation

    The test expects login to be called with argument 'admin'.
  2. Step 2: Check actual method call

    The method is called with 'guest', which does not match the expectation.
  3. Final Answer:

    The method login is called with wrong argument -> Option C
  4. Quick Check:

    Expect argument mismatch causes failure [OK]
Hint: Match expected arguments exactly in mocks [OK]
Common Mistakes:
  • Calling method with different arguments
  • Confusing stub and expect syntax
  • Ignoring error raised by RSpec
5. You want to test a method that calls an external API method fetch_data on a Service object. How can you use mocking and stubbing together to test your method without calling the real API?
hard
A. Stub fetch_data to return fake data and mock to check it was called once
B. Call the real fetch_data method and ignore mocking
C. Mock fetch_data without stubbing its return value
D. Do not use mocking or stubbing; test with real API

Solution

  1. Step 1: Stub the API call to avoid real network

    Stub fetch_data to return controlled fake data, so tests run fast and reliably.
  2. Step 2: Mock to verify the method call

    Use mock to check fetch_data was called exactly once, ensuring your method triggers it.
  3. Final Answer:

    Stub fetch_data to return fake data and mock to check it was called once -> Option A
  4. Quick Check:

    Stub return + mock call count = test isolation [OK]
Hint: Stub return and mock call count together [OK]
Common Mistakes:
  • Calling real API in tests
  • Mocking without stubbing return value
  • Ignoring call verification
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard