More endpoint_location coverage.
diff --git a/openstack/endpoint_location_test.go b/openstack/endpoint_location_test.go
index 05cecf5..4e0569a 100644
--- a/openstack/endpoint_location_test.go
+++ b/openstack/endpoint_location_test.go
@@ -1,12 +1,15 @@
 package openstack
 
 import (
+	"fmt"
+	"net/http"
 	"strings"
 	"testing"
 
 	"github.com/rackspace/gophercloud"
 	tokens2 "github.com/rackspace/gophercloud/openstack/identity/v2/tokens"
 	th "github.com/rackspace/gophercloud/testhelper"
+	fake "github.com/rackspace/gophercloud/testhelper/client"
 )
 
 // Service catalog fixtures take too much vertical space!
@@ -106,3 +109,117 @@
 	})
 	th.CheckEquals(t, err.Error(), "Unexpected availability in endpoint query: wat")
 }
+
+func setupV3Responses(t *testing.T) {
+	// Mock the service query.
+	th.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+		w.Header().Add("Content-Type", "application/json")
+		fmt.Fprintf(w, `
+			{
+				"links": {
+					"next": null,
+					"previous": null
+				},
+				"services": [
+					{
+						"description": "Correct",
+						"id": "1234",
+						"name": "same",
+						"type": "same"
+					},
+					{
+						"description": "Bad Name",
+						"id": "9876",
+						"name": "different",
+						"type": "same"
+					}
+				]
+			}
+		`)
+	})
+
+	// Mock the endpoint query.
+	th.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+		th.TestFormValues(t, r, map[string]string{
+			"service_id": "1234",
+			"interface":  "public",
+		})
+
+		w.Header().Add("Content-Type", "application/json")
+		fmt.Fprintf(w, `
+			{
+				"endpoints": [
+					{
+						"id": "12",
+						"interface": "public",
+						"name": "the-right-one",
+						"region": "same",
+						"service_id": "1234",
+						"url": "https://correct:9000/"
+					},
+					{
+						"id": "14",
+						"interface": "public",
+						"name": "bad-region",
+						"region": "different",
+						"service_id": "1234",
+						"url": "https://bad-region:9001/"
+					}
+				],
+				"links": {
+					"next": null,
+					"previous": null
+				}
+			}
+    `)
+	})
+}
+
+func TestV3EndpointExact(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	setupV3Responses(t)
+
+	actual, err := V3EndpointURL(fake.ServiceClient(), gophercloud.EndpointOpts{
+		Type:         "same",
+		Name:         "same",
+		Region:       "same",
+		Availability: gophercloud.AvailabilityPublic,
+	})
+	th.AssertNoErr(t, err)
+	th.CheckEquals(t, actual, "https://correct:9000/")
+}
+
+func TestV3EndpointNoService(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
+	th.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+		w.Header().Add("Content-Type", "application/json")
+		fmt.Fprintf(w, `
+      {
+        "links": {
+          "next": null,
+          "previous": null
+        },
+        "services": []
+      }
+    `)
+	})
+
+	_, err := V3EndpointURL(fake.ServiceClient(), gophercloud.EndpointOpts{
+		Type:         "nope",
+		Name:         "same",
+		Region:       "same",
+		Availability: gophercloud.AvailabilityPublic,
+	})
+	th.CheckEquals(t, gophercloud.ErrServiceNotFound, err)
+}