Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Fake implementation of API library at runtime (development mode)
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  7 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Steven Ringo  
View profile  
 More options Nov 13 2012, 6:56 pm
From: Steven Ringo <goo...@stevenringo.com>
Date: Tue, 13 Nov 2012 15:56:23 -0800 (PST)
Local: Tues, Nov 13 2012 6:56 pm
Subject: Fake implementation of API library at runtime (development mode)

We have a requirement to talk to a third party payment provider via an http
API
While I am happy with the testing of this implementation and mocking these
calls where necessary, I am looking for a good way to do this in the
development environment.

The interactions with the provider have significant implications for the UI
that its unfeasible to test in an automated fashion.

I don't want to use VCR or mock the web requests, as this is too low level
and the exact implementation has not been finalised. This doesn't mean the
UI can't be tweaked and tested though, and it would be good to have an
implementation that can be changed to emit the desired response by for
example, changing a flag.

Here's where I am:

I have a class that proxies calls from the app to the API, and in testing
its trivial to mock the calls to Acme.new

class Acme
  def pay_money(amount)
    AcmeAPI::PayMoneyRequest.new({
      type: "Ca$h",
      subscriber: @subscriber
      amount: amount
    })
  end
end

class FakeAcme
  def pay_money(amount)
    canned_result = { invoice_number: "12345" }
  end
end

Assuming my app uses the Acme class as such:

class PurchaseProduct
  def buy_it_now
    acme = Acme.new(subscriber)
    result = acme.pay_money(product.price)
  end
end

If I want to replace Acme with FakeAcme, what is the best way to do this?

In another programming (cough) life, I probably would have done something
like:

class PurchaseProduct(acme_provider)
  def buy_it_now
    acme = acme_provider.new(subscriber)
    result = acme.pay_money
  end
end

and then use some sort of DI library to specify the acme_provider at
runtime.

I could do something like in the rails initializer to hack it too:

if Rails.env.development?
  Acme = FakeAcme
end

Any comments/ideas on this approach or examples of alternatives would be
great.

Thanks,

Steve


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Simon Russell  
View profile  
 More options Nov 13 2012, 7:14 pm
From: Simon Russell <si...@bellyphant.com>
Date: Wed, 14 Nov 2012 11:14:13 +1100
Local: Tues, Nov 13 2012 7:14 pm
Subject: Re: [rails-oceania] Fake implementation of API library at runtime (development mode)

I generally do something in between your DI and const-hack approach.
 Usually something like some sort of config class that can be asked for the
payment provider.  At least then your hack is not going to confuse people
as much.

In this sort of situation I'd almost always be suspicious that there'll
come a time when two payment providers are used in the system at once, or
at least that switching to another one will happen.  So I also try and
reduce the number of references to the config thing, even if that's just
through some factory type thing.  Although clearly at this stage you're not
going to know what will govern the choice between two payment providers, so
it's not really possible to make it any cleaner.

Not all "other programming (cough)" patterns are bad, although I'd say DI
is less relevant (and frequently used in lieu of a proper solution).

On Wed, Nov 14, 2012 at 10:56 AM, Steven Ringo <goo...@stevenringo.com>wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steve Hoeksema  
View profile  
 More options Nov 13 2012, 7:19 pm
From: Steve Hoeksema <st...@seven.net.nz>
Date: Wed, 14 Nov 2012 13:19:28 +1300
Local: Tues, Nov 13 2012 7:19 pm
Subject: Re: [rails-oceania] Fake implementation of API library at runtime (development mode)

fogs' Mock objects might be of interest

e.g. https://github.com/fog/fog/blob/master/lib/fog/aws/storage.rb#L120


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Sebastian Porto  
View profile  
 More options Nov 13 2012, 7:38 pm
From: Sebastian Porto <sebaspo...@gmail.com>
Date: Wed, 14 Nov 2012 11:37:56 +1100
Local: Tues, Nov 13 2012 7:37 pm
Subject: Re: [rails-oceania] Fake implementation of API library at runtime (development mode)

I think DI is a nice way to go. Combined with some constants in an
initializer.

     class PurchaseProduct
         def buy_it_now
             acme = acme_provider.new(subscriber)
             result = acme.pay_money
         end

         def acme_provider
             @acme_provider ||= ACME_PROVIDER
         end

         def acme_provider=(obj)
             @acme_provider = obj
         end
     end

     if Rails.env.development?
         ACME_PROVIDER  = FakeAcme
     else
         ACME_PROVIDER  = Acme
     end

It is also very easy to swap the dependency in the test:

     pp = PurchaseProduct.new
     pp.acme_provider = FakeAcme

Sebastian


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jon Rowe  
View profile  
 More options Nov 14 2012, 4:39 am
From: Jon Rowe <m...@jonrowe.co.uk>
Date: Wed, 14 Nov 2012 09:39:21 +0000
Local: Wed, Nov 14 2012 4:39 am
Subject: Re: [rails-oceania] Fake implementation of API library at runtime (development mode)

Not overly relevant but I like how OmniAuth allows you to put it into test mode so it will return fake data rather than hitting providers. Very useful in development mode!

Also I tend to configure my APIs on a per environment basis, and have those settings in the relevant environment/#{env}.rb file. I find this to be a lot more flexible/cleaner than littering code with Rails.env.environment? calls.

Jon Rowe
-----------------------------
m...@jonrowe.co.uk
jonrowe.co.uk


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jamesl  
View profile  
 More options Nov 14 2012, 4:04 pm
From: jamesl <ladd.ja...@gmail.com>
Date: Wed, 14 Nov 2012 13:04:32 -0800 (PST)
Local: Wed, Nov 14 2012 4:04 pm
Subject: Re: Fake implementation of API library at runtime (development mode)

Did this sort of thing yesterday, adding to config/initializers to setup
the default provider and then in
config/environments overriding as necessary.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Simon Russell  
View profile  
 More options Nov 14 2012, 5:58 pm
From: Simon Russell <si...@bellyphant.com>
Date: Thu, 15 Nov 2012 09:58:38 +1100
Local: Wed, Nov 14 2012 5:58 pm
Subject: Re: [rails-oceania] Re: Fake implementation of API library at runtime (development mode)

The not using Rails.env.development? call is certainly a good idea, I
usually use a config yaml file, rather than the config/environment things
(that way I can configure it in production with capistrano or chef,
depending on need).


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »