Add support for feature testing without touching Mailchimp
Closed this issue · 2 comments
I've been using Gibbon for many years and it's been great.
Recently I ran into an issue where my feature specs were failing while trying subscribe users. The failure was
bad URI(is not URI?): https://key.api.mailchimp.com/3.0/lists/fan list id from mailchimp/members @title=nil, @detail=nil, @body=nil, @raw_body=nil, @status_code=nil (Gibbon::MailChimpError)
./app/services/mail_chimp_service.rb:45:in `subscribe'
I have a service that wraps my interaction with Gibbon. It looks roughly like
# frozen_string_literal: true
class MailChimpService
...
def subscribe_and_welcome
return unless @user.mailchimp_subscribed_at.nil?
subscribe
@user.update_attributes(mailchimp_subscribed_at: Time.zone.now)
end
...
def subscribe
list.members.create( body: { email_address: @user.email, ... } )
end
private
def members_list
Gibbon::Request.new(api_key: <api key>).lists(<list id>).members
end
end
This works fine in all the specs except my cucumber suite. Because in all the other specs, I can easily stub the Gibbon::Request
object and responses etc.
I wonder if you've ever thought about a test mode that doesn't actually make the request but maybe always returns success.
As a fix for my code, I simply rewrite the class with mock methods and that works for testing.
# in features/support/gibbon.rb so only available to cucumber
module Gibbon
class Request
def lists(list_id)
MockLists.new(list_id)
end
end
class MockLists
def initialize(id)
@id = id
end
def members
MockMembers.new
end
end
class MockMembers
def create(*args); end
end
end
This is certainly not complete for all scenarios but it works for my limited set.
I wonder if it's worth building out? Would providing a set of feature spec ready classes or helpers be something you'd want to ship with this gem?
@bunnymatic Hi. Thanks for the note. Yes, a test mode is a nice idea that would be something I'd accept a PR for. I'd want to avoid having to write code for every endpoint MC as part of their API though. Any thoughts on how this could be done without predefining response code? Would a test mode flag that suppressed requests be enough?
Agreed - filling out their entire API seems like it might be a bit ridiculous. I hadn't thought it through too far. As you can see, my little patch works, but is pretty stupid and doesn't cover any kind of investigation into the expected response etc.
It feels like suppressing the requests (and just acting like everythings good) is a first step. In my case, i was able to test my service and with this mock code above, I was able to make an expectation that lists.members.create
was called with the right arguments. That's basically where I wanted to stop testing. Then I'm trusting that the Gibbon code is properly tested so that whatever happens in create
will work the way I expect.
It feels like a mock library (which might be something that could be done with a little bit of meta-programming) would at least allow folks to stub/expect on their usage of the Gibbon gem.
I may try to flesh something out. If I do, I'll definitely send up a PR and you can see what you think.