diff --git a/test/fixtures/bing_madison_square_garden.json b/test/fixtures/bing_madison_square_garden
similarity index 100%
rename from test/fixtures/bing_madison_square_garden.json
rename to test/fixtures/bing_madison_square_garden
diff --git a/test/fixtures/bing_no_results.json b/test/fixtures/bing_no_results
similarity index 100%
rename from test/fixtures/bing_no_results.json
rename to test/fixtures/bing_no_results
diff --git a/test/fixtures/bing_reverse.json b/test/fixtures/bing_reverse
similarity index 100%
rename from test/fixtures/bing_reverse.json
rename to test/fixtures/bing_reverse
diff --git a/test/fixtures/freegeoip_74_200_247_59.json b/test/fixtures/freegeoip_74_200_247_59
similarity index 100%
rename from test/fixtures/freegeoip_74_200_247_59.json
rename to test/fixtures/freegeoip_74_200_247_59
diff --git a/test/fixtures/freegeoip_no_results.json b/test/fixtures/freegeoip_no_results
similarity index 100%
rename from test/fixtures/freegeoip_no_results.json
rename to test/fixtures/freegeoip_no_results
diff --git a/test/fixtures/geocoder_ca_madison_square_garden.json b/test/fixtures/geocoder_ca_madison_square_garden
similarity index 100%
rename from test/fixtures/geocoder_ca_madison_square_garden.json
rename to test/fixtures/geocoder_ca_madison_square_garden
diff --git a/test/fixtures/geocoder_ca_no_results.json b/test/fixtures/geocoder_ca_no_results
similarity index 100%
rename from test/fixtures/geocoder_ca_no_results.json
rename to test/fixtures/geocoder_ca_no_results
diff --git a/test/fixtures/geocoder_ca_reverse.json b/test/fixtures/geocoder_ca_reverse
similarity index 100%
rename from test/fixtures/geocoder_ca_reverse.json
rename to test/fixtures/geocoder_ca_reverse
diff --git a/test/fixtures/google_garbage.json b/test/fixtures/google_garbage
similarity index 100%
rename from test/fixtures/google_garbage.json
rename to test/fixtures/google_garbage
diff --git a/test/fixtures/google_madison_square_garden.json b/test/fixtures/google_madison_square_garden
similarity index 100%
rename from test/fixtures/google_madison_square_garden.json
rename to test/fixtures/google_madison_square_garden
diff --git a/test/fixtures/google_no_city_data.json b/test/fixtures/google_no_city_data
similarity index 100%
rename from test/fixtures/google_no_city_data.json
rename to test/fixtures/google_no_city_data
diff --git a/test/fixtures/google_no_locality.json b/test/fixtures/google_no_locality
similarity index 100%
rename from test/fixtures/google_no_locality.json
rename to test/fixtures/google_no_locality
diff --git a/test/fixtures/google_no_results.json b/test/fixtures/google_no_results
similarity index 100%
rename from test/fixtures/google_no_results.json
rename to test/fixtures/google_no_results
diff --git a/test/fixtures/mapquest_madison_square_garden.json b/test/fixtures/mapquest_madison_square_garden
similarity index 100%
rename from test/fixtures/mapquest_madison_square_garden.json
rename to test/fixtures/mapquest_madison_square_garden
diff --git a/test/fixtures/mapquest_no_results.json b/test/fixtures/mapquest_no_results
similarity index 100%
rename from test/fixtures/mapquest_no_results.json
rename to test/fixtures/mapquest_no_results
diff --git a/test/fixtures/maxmind_74_200_247_59.txt b/test/fixtures/maxmind_74_200_247_59
similarity index 100%
rename from test/fixtures/maxmind_74_200_247_59.txt
rename to test/fixtures/maxmind_74_200_247_59
diff --git a/test/fixtures/maxmind_invalid_key.txt b/test/fixtures/maxmind_invalid_key
similarity index 100%
rename from test/fixtures/maxmind_invalid_key.txt
rename to test/fixtures/maxmind_invalid_key
diff --git a/test/fixtures/maxmind_no_results.txt b/test/fixtures/maxmind_no_results
similarity index 100%
rename from test/fixtures/maxmind_no_results.txt
rename to test/fixtures/maxmind_no_results
diff --git a/test/fixtures/nominatim_madison_square_garden.json b/test/fixtures/nominatim_madison_square_garden
similarity index 100%
rename from test/fixtures/nominatim_madison_square_garden.json
rename to test/fixtures/nominatim_madison_square_garden
diff --git a/test/fixtures/nominatim_no_results.json b/test/fixtures/nominatim_no_results
similarity index 100%
rename from test/fixtures/nominatim_no_results.json
rename to test/fixtures/nominatim_no_results
diff --git a/test/fixtures/yahoo_error.json b/test/fixtures/yahoo_error
similarity index 100%
rename from test/fixtures/yahoo_error.json
rename to test/fixtures/yahoo_error
diff --git a/test/fixtures/yahoo_invalid_key.json b/test/fixtures/yahoo_invalid_key
similarity index 100%
rename from test/fixtures/yahoo_invalid_key.json
rename to test/fixtures/yahoo_invalid_key
diff --git a/test/fixtures/yahoo_madison_square_garden.json b/test/fixtures/yahoo_madison_square_garden
similarity index 100%
rename from test/fixtures/yahoo_madison_square_garden.json
rename to test/fixtures/yahoo_madison_square_garden
diff --git a/test/fixtures/yahoo_no_results.json b/test/fixtures/yahoo_no_results
similarity index 100%
rename from test/fixtures/yahoo_no_results.json
rename to test/fixtures/yahoo_no_results
diff --git a/test/fixtures/yahoo_over_limit.json b/test/fixtures/yahoo_over_limit
similarity index 100%
rename from test/fixtures/yahoo_over_limit.json
rename to test/fixtures/yahoo_over_limit
diff --git a/test/fixtures/yandex_invalid_key.json b/test/fixtures/yandex_invalid_key
similarity index 100%
rename from test/fixtures/yandex_invalid_key.json
rename to test/fixtures/yandex_invalid_key
diff --git a/test/fixtures/yandex_kremlin.json b/test/fixtures/yandex_kremlin
similarity index 100%
rename from test/fixtures/yandex_kremlin.json
rename to test/fixtures/yandex_kremlin
diff --git a/test/fixtures/yandex_no_results.json b/test/fixtures/yandex_no_results
similarity index 100%
rename from test/fixtures/yandex_no_results.json
rename to test/fixtures/yandex_no_results
diff --git a/test/test_helper.rb b/test/test_helper.rb
index f1b526c13732da9397f1985ca1c1b2ec7f38d532..6fca5010f64d82ecd2dfd1cd5d1ee8bbc34d8c70 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -73,7 +73,11 @@ require "geocoder/lookups/base"
 module Geocoder
   module Lookup
     class Base
-      private #-----------------------------------------------------------------
+      private
+      def fixture_exists?(filename)
+        File.exist?(File.join("test", "fixtures", filename))
+      end
+
       def read_fixture(file)
         filepath = File.join("test", "fixtures", file)
         s = File.read(filepath).strip.gsub(/\n\s*/, "")
@@ -83,140 +87,56 @@ module Geocoder
         end
         s
       end
-    end
-
-    class Google < Base
-      private #-----------------------------------------------------------------
-      def make_api_request(query)
-        raise TimeoutError if query.text == "timeout"
-        raise SocketError if query.text == "socket_error"
-        file = case query.text
-          when "no results";   :no_results
-          when "no locality";  :no_locality
-          when "no city data"; :no_city_data
-          else                 :madison_square_garden
-        end
-        read_fixture "google_#{file}.json"
-      end
-    end
-
-    class GooglePremier < Google
-    end
 
-    class Yahoo < Base
-      private #-----------------------------------------------------------------
-      def make_api_request(query)
-        raise TimeoutError if query.text == "timeout"
-        raise SocketError if query.text == "socket_error"
-        file = case query.text
-          when "no results"; :no_results
-          when "over limit"; :over_limit
-          when "invalid key"; :invalid_key
-          when "error";      :error
-          else               :madison_square_garden
-        end
-        read_fixture "yahoo_#{file}.json"
+      def default_fixture_filename
+        "#{fixture_prefix}_madison_square_garden"
       end
-    end
 
-    class Yandex < Base
-      private #-----------------------------------------------------------------
-      def make_api_request(query)
-        raise TimeoutError if query.text == "timeout"
-        raise SocketError if query.text == "socket_error"
-        file = case query.text
-          when "no results";  :no_results
-          when "invalid key"; :invalid_key
-          else                :kremlin
-        end
-        read_fixture "yandex_#{file}.json"
+      def fixture_prefix
+        handle
       end
-    end
 
-    class GeocoderCa < Base
-      private #-----------------------------------------------------------------
       def make_api_request(query)
         raise TimeoutError if query.text == "timeout"
         raise SocketError if query.text == "socket_error"
         if query.reverse_geocode?
-          read_fixture "geocoder_ca_reverse.json"
+          filename = "#{fixture_prefix}_reverse"
         else
-          file = case query.text
-            when "no results";  :no_results
-            else                :madison_square_garden
-          end
-          read_fixture "geocoder_ca_#{file}.json"
+          filename = "#{fixture_prefix}_#{query.text.gsub(" ", "_")}"
         end
-      end
-    end
-
-    class Freegeoip < Base
-      private #-----------------------------------------------------------------
-      def make_api_request(query)
-        raise TimeoutError if query.text == "timeout"
-        raise SocketError if query.text == "socket_error"
-        file = case query.text
-          when "no results";  :no_results
-          else                "74_200_247_59"
+        if fixture_exists?(filename)
+          read_fixture "#{filename}"
+        else
+          read_fixture default_fixture_filename
         end
-        read_fixture "freegeoip_#{file}.json"
       end
     end
 
-    class Maxmind < Base
-      private #-----------------------------------------------------------------
-      def make_api_request(query)
-        raise TimeoutError if query.text == "timeout"
-        raise SocketError if query.text == "socket_error"
-        file = case query.text
-          when "no results";  :no_results
-          when "invalid key"; :invalid_key
-          else                "74_200_247_59"
-        end
-        read_fixture "maxmind_#{file}.txt"
+    class GooglePremier
+      private
+      def fixture_prefix
+        "google"
       end
     end
 
-    class Bing < Base
-      private #-----------------------------------------------------------------
-      def make_api_request(query)
-        raise TimeoutError if query.text == "timeout"
-        raise SocketError if query.text == "socket_error"
-        if query.reverse_geocode?
-          read_fixture "bing_reverse.json"
-        else
-          file = case query.text
-            when "no results";  :no_results
-            else                :madison_square_garden
-          end
-          read_fixture "bing_#{file}.json"
-        end
+    class Yandex
+      private
+      def default_fixture_filename
+        "yandex_kremlin"
       end
     end
 
-    class Nominatim < Base
-      private #-----------------------------------------------------------------
-      def make_api_request(query)
-        raise TimeoutError if query.text == "timeout"
-        raise SocketError if query.text == "socket_error"
-        file = case query.text
-          when "no results";  :no_results
-          else                :madison_square_garden
-        end
-        read_fixture "nominatim_#{file}.json"
+    class Freegeoip
+      private
+      def default_fixture_filename
+        "freegeoip_74_200_247_59"
       end
     end
 
-    class Mapquest < Base
-      private #-----------------------------------------------------------------
-      def make_api_request(query)
-        raise TimeoutError if query.text == "timeout"
-        raise SocketError if query.text == "socket_error"
-        file = case query.text
-          when "no results";  :no_results
-          else                :madison_square_garden
-        end
-        read_fixture "mapquest_#{file}.json"
+    class Maxmind
+      private
+      def default_fixture_filename
+        "maxmind_74_200_247_59"
       end
     end