Skip to content

Instantly share code, notes, and snippets.

@pda
Created March 28, 2012 08:52
Show Gist options
  • Save pda/2224862 to your computer and use it in GitHub Desktop.
Save pda/2224862 to your computer and use it in GitHub Desktop.
Simple Dependency Injection and MiniTest::Mock
require "addressable/uri"
require "net/http"
module Ralexa
class Client
# Hacked to simplify example. Full version at:
# https://github.com/flippa/ralexa/blob/master/lib/ralexa/client.rb
def initialize(*credentials)
# ...
end
# Dependency injectors.
attr_writer :net_http
def get(host, path, query_values)
uri = signed_uri(host, path, query_values)
net_http.get(uri)
end
private
def signed_uri(host, path, query_values)
# ...
end
##
# Injectable dependencies.
def net_http
@net_http || Net::HTTP
end
end
end
require_relative "spec_helper"
module Ralexa
describe Client do
# Hacked to simplify example. Full version at:
# https://github.com/flippa/ralexa/blob/master/spec/client_spec.rb
let(:client) do
Client.new("id", "secret").tap do |c|
c.net_http = net_http
end
end
let(:net_http) { MiniTest::Mock.new }
let(:response) { MiniTest::Mock.new }
it "returns the response body of HTTP GET to a signed URI" do
net_http.expect :get_response, "<xml/>", [ %r{^http://example.org/test\?.*Signature=} ]
client.get("example.org", "/test", "a" => "b").must_equal "<xml/>"
end
end
end
require "base64"
require "digest/sha2"
require "openssl"
module Ralexa
class UriSigner
# Hacked to simplify example. Full version at:
# https://github.com/flippa/ralexa/blob/master/lib/ralexa/uri_signer.rb
def initialize(*credentials)
# ...
end
# dependency injectors
attr_writer :digest
attr_writer :hmac_signer
attr_writer :base64_encoder
attr_writer :time_utc
def sign_uri(original_uri)
# there's more to it than this, but to illustrate dependency injection:
original_uri.dup.tap do |uri|
uri.query_values = uri.query_values.merge(
"Timestamp" => time_utc.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"Signature" => base64_encoder.encode64(hmac_signer.digest(digest, @key, uri.to_s))
)
end
end
private
##
# Injectable dependencies.
def digest
@digest ||= OpenSSL::Digest::SHA256.new
end
def hmac_signer
@hmac_signer || OpenSSL::HMAC
end
def base64_encoder
@base64_encoder || Base64
end
def time_utc
@time_utc || Time.now.utc
end
end
end
require_relative "spec_helper"
require "addressable/uri"
module Ralexa
describe UriSigner do
# Hacked to simplify example. Full version at:
# https://github.com/flippa/ralexa/blob/master/spec/uri_signer_spec.rb
# UriSigner with dependencies injected.
def signer
UriSigner.new("id", "secret").tap do |rs|
rs.digest = digest
rs.hmac_signer = hmac_signer
rs.base64_encoder = base64_encoder
rs.time_utc = time_utc
end
end
# Mocked dependencies.
let(:digest) { MiniTest::Mock.new }
let(:hmac_signer) { MiniTest::Mock.new }
let(:base64_encoder) { MiniTest::Mock.new }
let(:time_utc) { Time.now.utc }
# Mock expectations and return values.
before do
hmac_signer.expect :digest, "the_hmac", [ digest, "secret", String ]
base64_encoder.expect :encode64, "base64_encoded\n", [ "the_hmac" ]
end
describe "for http://example.org/path?a=b" do
it "returns a signed URL" do
original_uri = Addressable::URI.parse("http://example.org/path?a=b")
signer.signed_uri(original_uri).query_values.must_equal(
"a" => "b",
"Signature" => "base64_encoded",
"Timestamp" => time_utc.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment