Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
The Anatomy of a mocked call - RuLu 2014
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Penelope Phippen
June 18, 2014
Technology
190
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
The Anatomy of a mocked call - RuLu 2014
Penelope Phippen
June 18, 2014
More Decks by Penelope Phippen
See All by Penelope Phippen
Introducing Rubyfmt
penelope_zone
0
630
How RSpec Works
penelope_zone
0
6.9k
Quick and easy browser testing using RSpec and Rails 5.1
penelope_zone
1
120
Teaching RSpec to play nice with Rails
penelope_zone
2
190
Little machines that eat strings
penelope_zone
1
150
What is processor (brighton ruby edition)
penelope_zone
0
150
What is processor?
penelope_zone
1
390
extremely defensive coding - rubyconf edition
penelope_zone
0
300
Agile, etc.
penelope_zone
2
270
Other Decks in Technology
See All in Technology
AI Search (Foundry IQ) におけるRAGデータの準備と配置
ryomaru0825
1
100
なぜAI時代に技術記事を書くのか?どう書くのか? 〜bunの場合〜
kworkdev
PRO
0
1.1k
AI秘書と毎日働くのはもう当たり前。開発以外の業務に足りない機能をどう埋める?
minorun365
PRO
4
2k
今から始めるAWS環境の暗号移行 - ポスト量子時代に備える
sato4mi
0
130
AI駆動開発におけるハーネスエンジニアリングの勘所
tsukuboshi
1
890
外国人エンジニアがVueプロトタイプで仕様を合わせている話 / Vue Fes Japan 2026 LT
eluwing
0
330
AI時代のエンジニアの情報発信〜個人の発信を組織の力に変える〜
ryo_kawamata
0
5.1k
Don't write the architecture only in the prompt.
neohsu
0
270
AWS Continuum for Penetration Testing に Deep Dive してみる
asanoharuki
2
1.5k
アクセラレーターで実現するServiceNow活用の高速化 / ServiceNow World Forum 2026
visional_engineering_and_design
0
110
Autonomous AI Lakehouse - Live AI Hubから始めるセキュアなAIデータ活用 -
oracle4engineer
PRO
2
180
(swiftc) NonCopyableとライフタイム修飾子
teamhimeh
0
160
Featured
See All Featured
Context Engineering - Making Every Token Count
addyosmani
9
1.3k
How to build a perfect <img>
jonoalderson
1
6.2k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
660
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
440
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
540
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
500
A Tale of Four Properties
chriscoyier
163
24k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
540
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
Why Our Code Smells
bkeepers
PRO
340
58k
Everyday Curiosity
cassininazir
0
380
Transcript
The Anatomy of a mocked call
!/samphippen
Hello everyone :)
Why is testing?
x`
None
Tests force behaviour
Without tests Anything could happen
Unit Testing makes me happy :)
Stubbing and mocking
Stubbing
Fake response to a method
allow(x).to( receive(:foo).and_return(3) )
x.foo will return 3
Mocking
Testing methods get called
expect(x).to receive(:foo)
Test fails if x does not receive foo
expect(x).to receive(:foo).with(3)
expect(x).to( receive(:foo) .with(3) .exactly(4).times )
How does it work?
Stubs
it “does something” do allow(foo).to receive(:bar) expect(foo.bar).to eq(nil) end
it “does something” do allow(foo).to receive(:bar) expect(foo.bar).to eq(nil) end
allow is syntax sugar for AllowanceTarget.new
Allowance Target
Allowance Target TargetBase
AllowanceTarget calls #delegate_to with :setup_allowance on TargetBase
Allowance Target TargetBase
TargetBase defines #to on AllowanceTarget
Defined #to calls :setup_allowance on matchers passed to #to
Allowance Target TargetBase
it “does something” do allow(foo).to receive(:bar) expect(foo.bar).to eq(nil) end
Things passed to #to are called “matchers”
Receive is a commonly used mocking/stubbing matcher
AllowanceTarget#to calls setup_allowance on the passed matcher
Allowance Target TargetBase Allowance Target TargetBase Receive
Receive#setup_allowance creates a Mock Proxy for object
Receive#setup_allowance calls #add_stub on the Mock Proxy
Allowance Target TargetBase Receive Proxy
Proxy objects manage all mocks/stubs for an object
it “does something” do allow(foo).to receive(:bar) allow(foo).to receive(:baz) expect(foo.bar).to eq(nil)
end
Proxy#add_stub creates a MethodDouble for the stubbed method
Allowance Target TargetBase Proxy Receive Method Double
MethodDouble saves the original implementation
MethodDouble creates stub implementation
it “does something” do allow(foo).to receive(:bar) expect(foo.bar).to eq(nil) end
it “does something” do allow(foo).to receive(:bar) expect(foo.bar).to eq(nil) end
foo.bar is the stubbed implementation
Call foo.bar
Method Double Call foo.bar
Method Double Call foo.bar Proxy
Method Double Call foo.bar Proxy Invokes stub
Method Double Call foo.bar Proxy Invokes stub Return value
it “does something” do allow(foo).to receive(:bar) expect(foo.bar).to eq(nil) end
RSpec manages lifecycle of mocks
RSpec::Mocks.setup
RSpec::Mocks.setup Your test
RSpec::Mocks.setup Your test RSpec::Mocks.verify
RSpec::Mocks.teardown RSpec::Mocks.setup Your test RSpec::Mocks.verify
All of this happens in a mock space
Allowance Target TargetBase Proxy Receive Method Double
RSpec::Mocks.teardown calls #reset_all on the current Space
Space#reset_all calls #reset on each proxy
Proxy#reset calls #reset on each MethodDouble
MethodDouble#reset returns original methods to objects
RSpec::Mocks.teardown RSpec::Mocks.setup Your test RSpec::Mocks.verify
Phew
Mocks
it “does something” do expect(foo).to receive(:bar).with(3) expect(foo.bar(3)).to eq(nil) end
expect is syntax sugar for ExpectationTarget.new
Expectation Target TargetBase Proxy Receive Method Double
Calls #setup_expectation
it “does something” do expect(foo).to receive(:bar).with(3) expect(foo.bar(3)).to eq(nil) end
Receive stores details of stubbed/ mocked implementation
Expectation Target TargetBase Proxy Receive Method Double
Method Double Call foo.bar Proxy Invokes stub Return value
Proxy callback checks arguments
Proxy raises if args don’t match
it “does something” do expect(foo).to receive(:bar).with(3) expect(foo.bar(3)).to eq(nil) end
RSpec::Mocks.teardown RSpec::Mocks.setup Your test RSpec::Mocks.verify
RSpec::Mocks.verify calls Space#verify_all
Space#verify_all calls #verify on each Proxy
Proxy raises if mock not called
And that’s how it all works :)
RSpec::Mocks.teardown RSpec::Mocks.setup Your test RSpec::Mocks.verify
expect(x).to receive(:foo) allow(x).to receive(:foo)
Target TargetBase
expect(x).to receive(:foo) allow(x).to receive(:foo)
Target TargetBase
expect(x).to receive(:foo) allow(x).to receive(:foo)
Receive
Proxy Receive
Proxy Receive Method Double
Target TargetBase Proxy Receive Method Double
Method Double Call foo.bar Proxy Invokes stub Return value
Target TargetBase Proxy Receive Method Double
RSpec 3.0.0 is out Please use it
tinyurl.com/ samrl2014
Let’s have some questions !/samphippen
[email protected]