Reputation: 4749
I'm writing a Rails app to send text messages using the Twilio API:
http://www.twilio.com/docs/api/rest/sending-sms
and to this end, I do:
client = Twilio::REST::Client.new account_sid, auth_token
client.account.sms.messages.create({
# stuff ...
})
That's all good and nice -- however, I don't want my tests to send a bunch of text messages because that would be stupid. So, I'd like to override Twilio::REST::Client.new to give me an object that'll let me call acccount.sms.messages.create
in my tests without undue fuss.
I have a solution that works, but feels ugly:
def mock_twilio_service(stub_client)
Twilio::REST::Client.stub :new, stub_client do
yield
end
end
class Recordy
attr_accessor :calls
def initialize
@calls = []
end
def method_missing(method, *args)
ret = self.class.new
@calls << {
method: method,
args: args,
block_given: block_given?,
ret: ret
}
yield if block_given?
ret
end
end
and then in my test:
test "send a text" do
cli = Recordy.new
mock_twilio_service cli do
# ... stuff
end
end
I feel like I'm missing something Super Obvious, but I'm not sure. Am I? Or am I totally barking up the wrong tree? (Yes, I've looked at How do I mock a Class with Ruby? but I don't think it's quite the same...?)
Upvotes: 2
Views: 2104
Reputation: 533
Another idea would be to use WebMock. As your client is making requests to Twilio. You can just stub out the requests. Within the stub you can also define what is returned from the requests and with which parameters it can be called.
And when you set
WebMock.disable_net_connect!
it is sure that no real requests can be made from the test.
This way you don't change any behavior of your test and will not rely on an external API for your tests to pass.
Upvotes: 1
Reputation: 10366
Twilio evangelist here.
We wrote Test Credentials exactly for this scenario. Test Credentials are a special set of credentials (AccountSid and AuthToken) that you can use when you make requests to the Twilio REST API that tell it to basically just go through the motions of making a phone call or sending a text message, but not actually do it (or charge you for it).
You can also use a special set of phone numbers to get Twilio to return specific success or error conditions.
You can find your test credentials in your Twilio dashboard.
Hope that helps.
Upvotes: 2