mirror of
https://github.com/jbranchaud/til
synced 2026-01-17 05:58:01 +00:00
Add Create Mock Class That Can Be Overridden as a Ruby TIL
This commit is contained in:
@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
|
|||||||
|
|
||||||
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
||||||
|
|
||||||
_1699 TILs and counting..._
|
_1700 TILs and counting..._
|
||||||
|
|
||||||
See some of the other learning resources I work on:
|
See some of the other learning resources I work on:
|
||||||
|
|
||||||
@@ -1357,6 +1357,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
|||||||
- [Create a CSV::Table Object](ruby/create-a-csv-table-object.md)
|
- [Create a CSV::Table Object](ruby/create-a-csv-table-object.md)
|
||||||
- [Create A Hash From An Array Of Arrays](ruby/create-a-hash-from-an-array-of-arrays.md)
|
- [Create A Hash From An Array Of Arrays](ruby/create-a-hash-from-an-array-of-arrays.md)
|
||||||
- [Create Listing Of All Middleman Pages](ruby/create-listing-of-all-middleman-pages.md)
|
- [Create Listing Of All Middleman Pages](ruby/create-listing-of-all-middleman-pages.md)
|
||||||
|
- [Create Mock Class That Can Be Overridden](ruby/create-mock-class-that-can-be-overridden.md)
|
||||||
- [Create Named Structs With Struct.new](ruby/create-named-structs-with-struct-new.md)
|
- [Create Named Structs With Struct.new](ruby/create-named-structs-with-struct-new.md)
|
||||||
- [Create Thumbnail Image For A PDF](ruby/create-thumbnail-image-for-a-pdf.md)
|
- [Create Thumbnail Image For A PDF](ruby/create-thumbnail-image-for-a-pdf.md)
|
||||||
- [Decompose Unicode Character With Diacritic Mark](ruby/decompose-unicode-character-with-diacritic-mark.md)
|
- [Decompose Unicode Character With Diacritic Mark](ruby/decompose-unicode-character-with-diacritic-mark.md)
|
||||||
|
|||||||
85
ruby/create-mock-class-that-can-be-overridden.md
Normal file
85
ruby/create-mock-class-that-can-be-overridden.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Create Mock Class That Can Be Overridden
|
||||||
|
|
||||||
|
Let's say I've defined a `MockTwilioClient` class for my system tests so that
|
||||||
|
they don't have to actually make calls out to the Twilio API.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class MockTwilioClient
|
||||||
|
def send_sms_message
|
||||||
|
"MSG_SID_123"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, any test that is exercising behavior that uses those parts of the
|
||||||
|
`TwilioClient` can mock those calls in a predictable way.
|
||||||
|
|
||||||
|
The above class always is successful when `send_sms_message` is called. What if
|
||||||
|
we want to simulate an error response? We need a way to override the client for
|
||||||
|
specific testing scenarios.
|
||||||
|
|
||||||
|
Let's create a helper that can create `MockTwilioClient` instances, either as is
|
||||||
|
or with overrides.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
def create_mock_twilio_client(&block)
|
||||||
|
if block_given?
|
||||||
|
Class.new(MockTwilioClient, &block).new
|
||||||
|
else
|
||||||
|
MockTwilioClient.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
If we pass it a block with specific method overrides, it will create a one-off
|
||||||
|
anonymous subclass of `MockTwilioClient` with that block which effectively
|
||||||
|
overrides the parent class's methods.
|
||||||
|
|
||||||
|
We can put this to use like so:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class SomeSystemTest < SystemTestCase
|
||||||
|
class MockTwilioClient
|
||||||
|
def send_sms_message
|
||||||
|
"MSG_SID_123"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_mock_twilio_client(&block)
|
||||||
|
if block_given?
|
||||||
|
Class.new(MockTwilioClient, &block).new
|
||||||
|
else
|
||||||
|
MockTwilioClient.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "send message to customer" do
|
||||||
|
mock_client = create_mock_twilio_client
|
||||||
|
|
||||||
|
TwilioClient.stub(:new, mock_client) do
|
||||||
|
# some action that uses `send_sms_message`
|
||||||
|
|
||||||
|
# some assertions ...
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "fail to send message to customer" do
|
||||||
|
mock_client = create_mock_twilio_client do
|
||||||
|
def send_sms_message
|
||||||
|
raise "Failed to send message"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
TwilioClient.stub(:new, mock_client) do
|
||||||
|
# some action that uses `send_sms_message`
|
||||||
|
|
||||||
|
# some assertions ...
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
In the second test case, I override the _success path_ with a version of
|
||||||
|
`send_sms_message` that raises an error.
|
||||||
Reference in New Issue
Block a user