diff --git a/package.json b/package.json
index f5129006..87b004ce 100644
--- a/package.json
+++ b/package.json
@@ -121,6 +121,7 @@
     "karma-mocha": "^0.2.2",
     "karma-phantomjs-launcher": "^1.0.0",
     "karma-webpack": "^1.7.0",
+    "matrix-mock-request": "^0.1.3",
     "minimist": "^1.2.0",
     "mkdirp": "^0.5.1",
     "mocha": "^2.4.5",
diff --git a/test/app-tests/joining.js b/test/app-tests/joining.js
index d9670125..11fd3d48 100644
--- a/test/app-tests/joining.js
+++ b/test/app-tests/joining.js
@@ -36,7 +36,7 @@ var expect = require('expect');
 var q = require('q');
 
 var test_utils = require('../test-utils');
-var MockHttpBackend = require('../mock-request');
+var MockHttpBackend = require('matrix-mock-request');
 
 var HS_URL='http://localhost';
 var IS_URL='http://localhost';
diff --git a/test/app-tests/loading.js b/test/app-tests/loading.js
index 54e98760..d01836a3 100644
--- a/test/app-tests/loading.js
+++ b/test/app-tests/loading.js
@@ -33,7 +33,7 @@ import {VIEWS} from 'matrix-react-sdk/lib/components/structures/MatrixChat';
 import dis from 'matrix-react-sdk/lib/dispatcher';
 
 import * as test_utils from '../test-utils';
-import MockHttpBackend from '../mock-request';
+import MockHttpBackend from 'matrix-mock-request';
 import {parseQs, parseQsFromFragment} from '../../src/vector/url_utils';
 
 var DEFAULT_HS_URL='http://my_server';
diff --git a/test/mock-request.js b/test/mock-request.js
deleted file mode 100644
index 64ac6c06..00000000
--- a/test/mock-request.js
+++ /dev/null
@@ -1,336 +0,0 @@
-"use strict";
-const q = require("q");
-import expect from 'expect';
-
-/**
- * Construct a mock HTTP backend, heavily inspired by Angular.js.
- * @constructor
- */
-function HttpBackend() {
-    this.requests = [];
-    this.expectedRequests = [];
-    const self = this;
-    // the request function dependency that the SDK needs.
-    this.requestFn = function(opts, callback) {
-        const req = new Request(opts, callback);
-        console.log(`${Date.now()} HTTP backend received request: ${req}`);
-        self.requests.push(req);
-
-        const abort = function() {
-            const idx = self.requests.indexOf(req);
-            if (idx >= 0) {
-                console.log("Aborting HTTP request: %s %s", opts.method,
-                            opts.uri);
-                self.requests.splice(idx, 1);
-                req.callback("aborted");
-            }
-        };
-
-        return {
-            abort: abort,
-        };
-    };
-
-    // very simplistic mapping from the whatwg fetch interface onto the request
-    // interface, so we can use the same mock backend for both.
-    this.fetchFn = function(input, init) {
-        init = init || {};
-        const requestOpts = {
-            uri: input,
-            method: init.method || 'GET',
-            body: init.body,
-        };
-
-        return new Promise((resolve, reject) => {
-            function callback(err, response, body) {
-                if (err) {
-                    reject(err);
-                }
-                resolve({
-                    ok: response.statusCode >= 200 && response.statusCode < 300,
-                    json: () => body,
-                });
-            };
-
-            const req = new Request(requestOpts, callback);
-            console.log(`HTTP backend received request: ${req}`);
-            self.requests.push(req);
-        });
-    };
-}
-HttpBackend.prototype = {
-    /**
-     * Respond to all of the requests (flush the queue).
-     * @param {string} path The path to flush (optional) default: all.
-     * @param {integer} numToFlush The number of things to flush (optional), default: all.
-     * @param {integer=} waitTime  The time (in ms) to wait for a request to happen.
-     *    default: 100
-     *
-     * @return {Promise} resolves when there is nothing left to flush, with the
-     *    number of requests flushed
-     */
-    flush: function(path, numToFlush, waitTime) {
-        const defer = q.defer();
-        const self = this;
-        let flushed = 0;
-        if (waitTime === undefined) {
-            waitTime = 100;
-        }
-
-        function log(msg) {
-            console.log(`${Date.now()} flush[${path || ''}]: ${msg}`);
-        }
-
-        log("HTTP backend flushing... (path=" + path
-            + " numToFlush=" + numToFlush
-            + " waitTime=" + waitTime
-            + ")",
-        );
-        const endTime =  waitTime + Date.now();
-
-        const tryFlush = function() {
-            // if there's more real requests and more expected requests, flush 'em.
-            log(`  trying to flush => reqs=[${self.requests}] ` +
-                `expected=[${self.expectedRequests}]`,
-            );
-            if (self._takeFromQueue(path)) {
-                // try again on the next tick.
-                flushed += 1;
-                if (numToFlush && flushed === numToFlush) {
-                    log(`Flushed assigned amount: ${numToFlush}`);
-                    defer.resolve(flushed);
-                } else {
-                    log(`  flushed. Trying for more.`);
-                    setTimeout(tryFlush, 0);
-                }
-            } else if (flushed === 0 && Date.now() < endTime) {
-                // we may not have made the request yet, wait a generous amount of
-                // time before giving up.
-                log(`  nothing to flush yet; waiting for requests.`);
-                setTimeout(tryFlush, 5);
-            } else {
-                if (flushed === 0) {
-                    log("nothing to flush; giving up");
-                } else {
-                    log(`no more flushes after flushing ${flushed} requests`);
-                }
-                defer.resolve(flushed);
-            }
-        };
-
-        setTimeout(tryFlush, 0);
-
-        return defer.promise;
-    },
-
-    /**
-     * Attempts to resolve requests/expected requests.
-     * @param {string} path The path to flush (optional) default: all.
-     * @return {boolean} true if something was resolved.
-     */
-    _takeFromQueue: function(path) {
-        let req = null;
-        let i;
-        let j;
-        let matchingReq = null;
-        let expectedReq = null;
-        let testResponse = null;
-        for (i = 0; i < this.requests.length; i++) {
-            req = this.requests[i];
-            for (j = 0; j < this.expectedRequests.length; j++) {
-                expectedReq = this.expectedRequests[j];
-                if (path && path !== expectedReq.path) {
-                    continue;
-                }
-                if (expectedReq.method === req.method &&
-                        req.path.indexOf(expectedReq.path) !== -1) {
-                    if (!expectedReq.data || (JSON.stringify(expectedReq.data) ===
-                            JSON.stringify(req.data))) {
-                        matchingReq = expectedReq;
-                        this.expectedRequests.splice(j, 1);
-                        break;
-                    }
-                }
-            }
-
-            if (matchingReq) {
-                // remove from request queue
-                this.requests.splice(i, 1);
-                i--;
-
-                for (j = 0; j < matchingReq.checks.length; j++) {
-                    matchingReq.checks[j](req);
-                }
-                testResponse = matchingReq.response;
-                console.log(`${Date.now()}    responding to ${matchingReq.path}`);
-                let body = testResponse.body;
-                if (Object.prototype.toString.call(body) == "[object Function]") {
-                    body = body(req.path, req.data);
-                }
-                req.callback(
-                    testResponse.err, testResponse.response, body,
-                );
-                matchingReq = null;
-            }
-        }
-        if (testResponse) {  // flushed something
-            return true;
-        }
-        return false;
-    },
-
-    /**
-     * Makes sure that the SDK hasn't sent any more requests to the backend.
-     */
-    verifyNoOutstandingRequests: function() {
-        const firstOutstandingReq = this.requests[0] || {};
-        expect(this.requests.length).toEqual(0,
-            "Expected no more HTTP requests but received request to " +
-            firstOutstandingReq.path,
-        );
-    },
-
-    /**
-     * Makes sure that the test doesn't have any unresolved requests.
-     */
-    verifyNoOutstandingExpectation: function() {
-        const firstOutstandingExpectation = this.expectedRequests[0] || {};
-        expect(this.expectedRequests.length).toEqual(0,
-            "Expected to see HTTP request for " + firstOutstandingExpectation.path,
-        );
-    },
-
-    /**
-     * Create an expected request.
-     * @param {string} method The HTTP method
-     * @param {string} path The path (which can be partial)
-     * @param {Object} data The expected data.
-     * @return {Request} An expected request.
-     */
-    when: function(method, path, data) {
-        const pendingReq = new ExpectedRequest(method, path, data);
-        this.expectedRequests.push(pendingReq);
-        return pendingReq;
-    },
-};
-
-/**
- * Represents the expectation of a request.
- *
- * <p>Includes the conditions to be matched against, the checks to be made,
- * and the response to be returned.
- *
- * @constructor
- * @param {string} method
- * @param {string} path
- * @param {object?} data
- */
-function ExpectedRequest(method, path, data) {
-    this.method = method;
-    this.path = path;
-    this.data = data;
-    this.response = null;
-    this.checks = [];
-}
-
-ExpectedRequest.prototype = {
-    toString: function() {
-        return this.method + " " + this.path
-    },
-
-    /**
-     * Execute a check when this request has been satisfied.
-     * @param {Function} fn The function to execute.
-     * @return {Request} for chaining calls.
-     */
-    check: function(fn) {
-        this.checks.push(fn);
-        return this;
-    },
-
-    /**
-     * Respond with the given data when this request is satisfied.
-     * @param {Number} code The HTTP status code.
-     * @param {Object|Function} data The HTTP JSON body. If this is a function,
-     * it will be invoked when the JSON body is required (which should be returned).
-     */
-    respond: function(code, data) {
-        this.response = {
-            response: {
-                statusCode: code,
-                headers: {},
-            },
-            body: data,
-            err: null,
-        };
-    },
-
-    /**
-     * Fail with an Error when this request is satisfied.
-     * @param {Number} code The HTTP status code.
-     * @param {Error} err The error to throw (e.g. Network Error)
-     */
-    fail: function(code, err) {
-        this.response = {
-            response: {
-                statusCode: code,
-                headers: {},
-            },
-            body: null,
-            err: err,
-        };
-    },
-};
-
-/**
- * Represents a request made by the app.
- *
- * @constructor
- * @param {object} opts opts passed to request()
- * @param {function} callback
- */
-function Request(opts, callback) {
-    this.opts = opts;
-    this.callback = callback;
-
-    Object.defineProperty(this, 'method', {
-        get: function() {
-            return opts.method;
-        },
-    });
-
-    Object.defineProperty(this, 'path', {
-        get: function() {
-            return opts.uri;
-        },
-    });
-
-    Object.defineProperty(this, 'data', {
-        get: function() {
-            return opts.body;
-        },
-    });
-
-    Object.defineProperty(this, 'queryParams', {
-        get: function() {
-            return opts.qs;
-        },
-    });
-
-    Object.defineProperty(this, 'headers', {
-        get: function() {
-            return opts.headers || {};
-        },
-    });
-}
-
-Request.prototype = {
-    toString: function() {
-        return this.method + " " + this.path;
-    },
-};
-
-/**
- * The HttpBackend class.
- */
-module.exports = HttpBackend;