Move setup() and teardown() into testhelper, too.
diff --git a/openstack/identity/v3/tokens/requests_test.go b/openstack/identity/v3/tokens/requests_test.go
index db0fba7..77b49f3 100644
--- a/openstack/identity/v3/tokens/requests_test.go
+++ b/openstack/identity/v3/tokens/requests_test.go
@@ -12,16 +12,16 @@
 
 // authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure.
 func authTokenPost(t *testing.T, options gophercloud.AuthOptions, scope *Scope, requestJSON string) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 
 	client := gophercloud.ServiceClient{
-		Endpoint: endpoint(),
+		Endpoint: testhelper.Endpoint(),
 		Options:  options,
 		TokenID:  "12345abcdef",
 	}
 
-	mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
+	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "POST")
 		testhelper.TestHeader(t, r, "Content-Type", "application/json")
 		testhelper.TestHeader(t, r, "Accept", "application/json")
@@ -38,11 +38,11 @@
 }
 
 func authTokenPostErr(t *testing.T, options gophercloud.AuthOptions, scope *Scope, includeToken bool, expectedErr error) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 
 	client := gophercloud.ServiceClient{
-		Endpoint: endpoint(),
+		Endpoint: testhelper.Endpoint(),
 		Options:  options,
 	}
 	if includeToken {
@@ -237,15 +237,15 @@
 }
 
 func TestCreateExtractsTokenFromResponse(t *testing.T) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 
 	client := gophercloud.ServiceClient{
-		Endpoint: endpoint(),
+		Endpoint: testhelper.Endpoint(),
 		Options:  gophercloud.AuthOptions{UserID: "me", Password: "shhh"},
 	}
 
-	mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
+	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
 		w.Header().Add("X-Subject-Token", "aaa111")
 
 		w.WriteHeader(http.StatusCreated)
@@ -388,15 +388,15 @@
 }
 
 func TestInfoRequest(t *testing.T) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 
 	client := gophercloud.ServiceClient{
-		Endpoint: endpoint(),
+		Endpoint: testhelper.Endpoint(),
 		TokenID:  "12345abcdef",
 	}
 
-	mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
+	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "GET")
 		testhelper.TestHeader(t, r, "Content-Type", "application/json")
 		testhelper.TestHeader(t, r, "Accept", "application/json")
@@ -427,11 +427,11 @@
 
 func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) gophercloud.ServiceClient {
 	client := gophercloud.ServiceClient{
-		Endpoint: endpoint(),
+		Endpoint: testhelper.Endpoint(),
 		TokenID:  "12345abcdef",
 	}
 
-	mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
+	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, expectedMethod)
 		testhelper.TestHeader(t, r, "Content-Type", "application/json")
 		testhelper.TestHeader(t, r, "Accept", "application/json")
@@ -445,8 +445,8 @@
 }
 
 func TestValidateRequestSuccessful(t *testing.T) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 	client := prepareAuthTokenHandler(t, "HEAD", http.StatusNoContent)
 
 	ok, err := Validate(&client, "abcdef12345")
@@ -460,8 +460,8 @@
 }
 
 func TestValidateRequestFailure(t *testing.T) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 	client := prepareAuthTokenHandler(t, "HEAD", http.StatusNotFound)
 
 	ok, err := Validate(&client, "abcdef12345")
@@ -475,8 +475,8 @@
 }
 
 func TestValidateRequestError(t *testing.T) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 	client := prepareAuthTokenHandler(t, "HEAD", http.StatusUnauthorized)
 
 	_, err := Validate(&client, "abcdef12345")
@@ -486,8 +486,8 @@
 }
 
 func TestRevokeRequestSuccessful(t *testing.T) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 	client := prepareAuthTokenHandler(t, "DELETE", http.StatusNoContent)
 
 	err := Revoke(&client, "abcdef12345")
@@ -497,8 +497,8 @@
 }
 
 func TestRevokeRequestError(t *testing.T) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 	client := prepareAuthTokenHandler(t, "DELETE", http.StatusNotFound)
 
 	err := Revoke(&client, "abcdef12345")
diff --git a/openstack/identity/v3/tokens/tokens_test.go b/openstack/identity/v3/tokens/tokens_test.go
deleted file mode 100644
index 46b8ca1..0000000
--- a/openstack/identity/v3/tokens/tokens_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package tokens
-
-import (
-	"net/http"
-	"net/http/httptest"
-)
-
-var (
-	mux    *http.ServeMux
-	server *httptest.Server
-)
-
-func setup() {
-	mux = http.NewServeMux()
-	server = httptest.NewServer(mux)
-}
-
-func teardown() {
-	server.Close()
-}
-
-func endpoint() string {
-	return server.URL + "/"
-}
diff --git a/openstack/identity/v3/tokens/urls_test.go b/openstack/identity/v3/tokens/urls_test.go
index bcfb7c4..5ff8bc6 100644
--- a/openstack/identity/v3/tokens/urls_test.go
+++ b/openstack/identity/v3/tokens/urls_test.go
@@ -4,15 +4,16 @@
 	"testing"
 
 	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/testhelper"
 )
 
 func TestTokenURL(t *testing.T) {
-	setup()
-	defer teardown()
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
 
-	client := gophercloud.ServiceClient{Endpoint: endpoint()}
+	client := gophercloud.ServiceClient{Endpoint: testhelper.Endpoint()}
 
-	expected := endpoint() + "auth/tokens"
+	expected := testhelper.Endpoint() + "auth/tokens"
 	actual := getTokenURL(&client)
 	if actual != expected {
 		t.Errorf("Expected URL %s, but was %s", expected, actual)
diff --git a/testhelper/http_responses.go b/testhelper/http_responses.go
index e6463a5..481a833 100644
--- a/testhelper/http_responses.go
+++ b/testhelper/http_responses.go
@@ -4,11 +4,36 @@
 	"encoding/json"
 	"io/ioutil"
 	"net/http"
+	"net/http/httptest"
 	"net/url"
 	"reflect"
 	"testing"
 )
 
+var (
+	// Mux is a multiplexer that can be used to register handlers.
+	Mux *http.ServeMux
+
+	// Server is an in-memory HTTP server for testing.
+	Server *httptest.Server
+)
+
+// SetupHTTP prepares the Mux and Server.
+func SetupHTTP() {
+	Mux = http.NewServeMux()
+	Server = httptest.NewServer(Mux)
+}
+
+// TeardownHTTP releases HTTP-related resources.
+func TeardownHTTP() {
+	Server.Close()
+}
+
+// Endpoint returns a fake endpoint that will actually target the Mux.
+func Endpoint() string {
+	return Server.URL + "/"
+}
+
 // TestFormValues ensures that all the URL parameters given to the http.Request are the same as values.
 func TestFormValues(t *testing.T, r *http.Request, values map[string]string) {
 	want := url.Values{}