Back to Repositories

Testing Bing Geocoding Integration in alexreisner/geocoder

This test suite validates the Bing geocoding lookup functionality in the Geocoder gem. It ensures proper handling of location queries, result parsing, and error conditions when interacting with Bing’s geocoding API.

Test Coverage Overview

The test suite provides comprehensive coverage of Bing geocoding operations, including:

  • Reverse geocoding query formation
  • Address component parsing
  • Viewport coordinate handling
  • Region-specific URL formatting
  • Error handling for various API responses

Implementation Analysis

The testing approach uses Ruby’s standard test framework with custom assertions for geocoding operations. It implements a structured setup pattern for API configuration and leverages mock responses to validate different scenarios. The tests follow a clear pattern of query construction, execution, and response validation.

Technical Details

Key technical components include:

  • GeocoderTestCase as the base test class
  • Bing API key configuration
  • Query URL construction validation
  • Response parsing for address components
  • Exception handling for API errors

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolated test cases with clear purpose
  • Comprehensive error scenario coverage
  • Consistent setup and teardown patterns
  • Thorough validation of API interaction points
  • Clean separation of concerns in test organization

alexreisner/geocoder

test/unit/lookups/bing_test.rb

            
# encoding: utf-8
require 'test_helper'

class BingTest < GeocoderTestCase

  def setup
    super
    Geocoder.configure(lookup: :bing)
    set_api_key!(:bing)
  end

  def test_query_for_reverse_geocode
    lookup = Geocoder::Lookup::Bing.new
    url = lookup.query_url(Geocoder::Query.new([45.423733, -75.676333]))
    assert_match(/Locations\/45.423733/, url)
  end

  def test_result_components
    result = Geocoder.search("Madison Square Garden, New York, NY").first
    assert_equal "Madison Square Garden, NY", result.address
    assert_equal "NY", result.state
    assert_equal "New York", result.city
  end

  def test_result_viewport
    result = Geocoder.search("Madison Square Garden, New York, NY").first
    assert_equal [
      40.744944289326668,
      -74.002353921532631,
      40.755675807595253,
      -73.983625397086143
    ], result.viewport
  end

  def test_no_results
    results = Geocoder.search("no results")
    assert_equal 0, results.length
  end

  def test_query_url_contains_region
    lookup = Geocoder::Lookup::Bing.new
    url = lookup.query_url(Geocoder::Query.new(
      "manchester",
      :region => "uk"
    ))
    assert_match(%r!Locations/uk/\?q=manchester!, url)
  end

  def test_query_url_without_region
    lookup = Geocoder::Lookup::Bing.new
    url = lookup.query_url(Geocoder::Query.new(
      "manchester"
    ))
    assert_match(%r!Locations/\?q=manchester!, url)
  end

  def test_query_url_escapes_spaces_in_address
    lookup = Geocoder::Lookup::Bing.new
    url = lookup.query_url(Geocoder::Query.new(
      "manchester, lancashire",
      :region => "uk"
    ))
    assert_match(%r!Locations/uk/\?q=manchester%2C%20lancashire!, url)
  end

  def test_query_url_strips_trailing_and_leading_spaces
    lookup = Geocoder::Lookup::Bing.new
    url = lookup.query_url(Geocoder::Query.new(
      " manchester, lancashire ",
      :region => "uk"
    ))
    assert_match(%r!Locations/uk/\?q=manchester%2C%20lancashire!, url)
  end

  def test_raises_exception_when_service_unavailable
    Geocoder.configure(:always_raise => [Geocoder::ServiceUnavailable])
    l = Geocoder::Lookup.get(:bing)
    assert_raises Geocoder::ServiceUnavailable do
      l.send(:results, Geocoder::Query.new("service unavailable"))
    end
  end

  def test_raises_exception_when_bing_returns_forbidden_request
    Geocoder.configure(:always_raise => [Geocoder::RequestDenied])
    assert_raises Geocoder::RequestDenied do
      Geocoder.search("forbidden request")
    end
  end

  def test_raises_exception_when_bing_returns_internal_server_error
    Geocoder.configure(:always_raise => [Geocoder::ServiceUnavailable])
    assert_raises Geocoder::ServiceUnavailable do
      Geocoder.search("internal server error")
    end
  end
end