diff --git a/README.md b/README.md
index ba10536..93d2a4a 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
 
 
 
-Library (written in TypeScript) to mock REST and GraphQL requests
+Library (written in TypeScript) to mock REST, GraphQL, and Websocket requests
 
 
 
@@ -93,13 +93,13 @@ import { AppModule } from './app/app.module';
 import { environment } from './environments/environment';
 
 async function setupMocks() {
-    const { injectMocks, extractScenarioFromLocation } = await import(
-      'data-mocks'
-    );
-    // You could just define your mocks inline if you didn't want to import them.
-    const { getMocks } = await import('./path/to/your/mock/definitions');
+  const { injectMocks, extractScenarioFromLocation } = await import(
+    'data-mocks'
+  );
+  // You could just define your mocks inline if you didn't want to import them.
+  const { getMocks } = await import('./path/to/your/mock/definitions');
 
-    injectMocks(getMocks(), extractScenarioFromLocation(window.location));
+  injectMocks(getMocks(), extractScenarioFromLocation(window.location));
 }
 
 async function main() {
@@ -303,6 +303,38 @@ const Component = () => {
 };
 ```
 
+### Basic Websocket server mock injection
+
+To mock a WebSocket server you should provide a function which takes a single `Server` (provided by `mock-socket`) as a paremeter. On this mock server parameter you can set your callbacks as normal. Please not that due to limitations in the underlying websocket mocking library, the url _must_ be supplied as a string, not a regular expression
+
+```ts
+const wsMock: WebSocketServerMock = s => {
+  return s.on('connection', socket => {
+    socket.on('message', _ => {
+      socket.send('hello world')
+      }
+    });
+  });
+};
+
+const mocks = {
+  default: [
+    {
+      url: 'ws://localhost' //notice this is NOT a regular expression
+      method: 'WEBSOCKET',
+      server: wsMock,
+    }
+  ]
+};
+
+injectMocks(mocks, extractScenarioFromLocation(window.location));
+
+
+const socket = new WebSocket('ws://localhost')
+socket.send('hello')
+
+```
+
 ## Exported types
 
 ### Scenarios
@@ -331,6 +363,14 @@ const Component = () => {
 | method     | string             | ✅       | Must be 'GRAPHQL' to specify that this is a GraphQL mock. |
 | operations | Array\ | ✅       | Array of GraphQL operations for this request.             |
 
+### WebSocketMock
+
+| Property | Type     | Required | Description                                                                                                   |
+| -------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------- |
+| url      | string   | ✅       | Regular expression that matches part of the URL.                                                              |
+| method   | string   | ✅       | Must be 'WEBSOCKET' to specify that this is a Websocket mock.                                                 |
+| server   | function | ✅       | a function which takes a server as a parameter. Here you will set up the functionality of the server to mock. |
+
 ### Mock
 
 Union type of [`HttpMock`](#HttpMock) and [`GraphQLMock`](#GraphQLMock).
diff --git a/jest.config.js b/jest.config.js
index ed0f2e1..2786a53 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,4 +1,4 @@
 module.exports = {
   preset: 'ts-jest',
-  testEnvironment: 'jsdom'
+  testEnvironment: 'jsdom',
 };
diff --git a/package.json b/package.json
index cbf0f49..beda6b3 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
   },
   "dependencies": {
     "fetch-mock": "^9.4.0",
+    "mock-socket": "^9.0.3",
     "query-string": "^5.1.1",
     "xhr-mock": "^2.5.1"
   },
diff --git a/src/mocks.test.ts b/src/mocks.test.ts
index 9670564..64d6d55 100644
--- a/src/mocks.test.ts
+++ b/src/mocks.test.ts
@@ -1,19 +1,63 @@
-import 'isomorphic-fetch';
 import axios from 'axios';
+import fetchMock from 'fetch-mock';
+import 'isomorphic-fetch';
+import XHRMock, { proxy } from 'xhr-mock';
 import {
-  injectMocks,
   extractScenarioFromLocation,
+  injectMocks,
   reduceAllMocksForScenario,
 } from './mocks';
-import { HttpMethod, Scenarios, MockConfig } from './types';
-import XHRMock, { proxy } from 'xhr-mock';
-import fetchMock from 'fetch-mock';
+import { HttpMethod, MockConfig, Scenarios } from './types';
 
 describe('data-mocks', () => {
   beforeEach(() => {
     fetchMock.resetHistory();
   });
 
+  describe('Websockets', () => {
+    const testURL = 'ws://localhost/foo';
+    it('Spawns a working websocket server', async () => {
+      const onMessage = jest.fn();
+      const onConnect = jest.fn();
+      const scenarios: Scenarios = {
+        default: [
+          {
+            url: testURL,
+            method: 'WEBSOCKET',
+            server: (s) => {
+              s.on('connection', (socket) => {
+                onConnect();
+                socket.on('message', (req) => {
+                  onMessage();
+                  socket.send(req.toString());
+                  s.close();
+                });
+              });
+            },
+          },
+        ],
+      };
+      injectMocks(scenarios, 'default');
+
+      const socket = new WebSocket(testURL);
+      let res;
+      socket.addEventListener('message', (data) => {
+        res = data.data;
+        socket.close();
+      });
+
+      await awaitSocket(socket, WebSocket.OPEN);
+      expect(onConnect).toBeCalled();
+
+      const message = 'hello world';
+      socket.send(message);
+      await awaitSocket(socket, WebSocket.CLOSED);
+      expect(onMessage).toBeCalled();
+
+      expect(res).toEqual(message);
+    });
+  });
+
   describe('REST', () => {
     describe('HTTP methods', () => {
       const httpMethods: HttpMethod[] = [
@@ -50,7 +94,6 @@ describe('data-mocks', () => {
           const xhrSpy = jest.spyOn(XHRMock, httpMethod.toLowerCase() as any);
 
           injectMocks(scenarios, 'default');
-
           expect(fetchSpy).toHaveBeenCalledTimes(2);
           expect(fetchSpy.mock.calls[0][0]).toEqual(/foo/);
           expect(fetchSpy.mock.calls[1][0]).toEqual(/bar/);
@@ -282,6 +325,8 @@ describe('data-mocks', () => {
   });
 
   describe('Scenarios', () => {
+    const websocketServerFn = jest.fn();
+    const anotherServerFn = jest.fn();
     const scenarios: Scenarios = {
       default: [
         {
@@ -299,6 +344,22 @@ describe('data-mocks', () => {
           responseHeaders: { token: 'bar' },
         },
         { url: /bar/, method: 'POST', response: {}, responseCode: 200 },
+        {
+          url: /graphql/,
+          method: 'GRAPHQL',
+          operations: [
+            {
+              operationName: 'Query',
+              type: 'query',
+              response: { data: { test: 'data' } },
+            },
+          ],
+        },
+        {
+          url: 'ws://localhost',
+          method: 'WEBSOCKET',
+          server: websocketServerFn,
+        },
       ],
       someScenario: [
         {
@@ -308,6 +369,18 @@ describe('data-mocks', () => {
           responseCode: 401,
         },
         { url: /baz/, method: 'POST', response: {}, responseCode: 200 },
+        {
+          url: /graphql/,
+          method: 'GRAPHQL',
+          operations: [
+            {
+              operationName: 'Query',
+              type: 'query',
+              response: { data: { test: 'different data' } },
+            },
+          ],
+        },
+        { url: 'ws://localhost', method: 'WEBSOCKET', server: anotherServerFn },
       ],
     };
 
@@ -340,6 +413,22 @@ describe('data-mocks', () => {
           responseHeaders: { token: 'bar' },
         },
         { url: /bar/, method: 'POST', response: {}, responseCode: 200 },
+        {
+          url: /graphql/,
+          method: 'GRAPHQL',
+          operations: [
+            {
+              operationName: 'Query',
+              type: 'query',
+              response: { data: { test: 'data' } },
+            },
+          ],
+        },
+        {
+          url: 'ws://localhost',
+          method: 'WEBSOCKET',
+          server: websocketServerFn,
+        },
       ]);
     });
 
@@ -367,6 +456,18 @@ describe('data-mocks', () => {
           responseCode: 200,
         },
         { url: /baz/, method: 'POST', response: {}, responseCode: 200 },
+        {
+          url: /graphql/,
+          method: 'GRAPHQL',
+          operations: [
+            {
+              operationName: 'Query',
+              type: 'query',
+              response: { data: { test: 'different data' } },
+            },
+          ],
+        },
+        { url: 'ws://localhost', method: 'WEBSOCKET', server: anotherServerFn },
       ]);
     });
 
@@ -536,3 +637,15 @@ describe('data-mocks', () => {
     });
   });
 });
+
+const awaitSocket = (socket, state) => {
+  return new Promise(function (resolve) {
+    setTimeout(function () {
+      if (socket.readyState === state) {
+        resolve(true);
+      } else {
+        awaitSocket(socket, state).then(resolve);
+      }
+    }, 1000);
+  });
+};
diff --git a/src/mocks.ts b/src/mocks.ts
index c954f35..1d5520a 100644
--- a/src/mocks.ts
+++ b/src/mocks.ts
@@ -1,6 +1,7 @@
 import fetchMock from 'fetch-mock';
 import XHRMock, { delay as xhrMockDelay, proxy } from 'xhr-mock';
 import { parse } from 'query-string';
+import { Server as MockServer } from 'mock-socket';
 import {
   Scenarios,
   MockConfig,
@@ -8,6 +9,7 @@ import {
   HttpMock,
   GraphQLMock,
   Operation,
+  WebSocketMock,
 } from './types';
 
 /**
@@ -43,14 +45,11 @@ export const injectMocks = (
   if (!mocks || mocks.length === 0) {
     throw new Error('Unable to instantiate mocks');
   }
-
-  const restMocks = mocks.filter((m) => m.method !== 'GRAPHQL') as HttpMock[];
-  const graphQLMocks = mocks.filter(
-    (m) => m.method === 'GRAPHQL'
-  ) as GraphQLMock[];
+  const { restMocks, graphQLMocks, webSocketMocks } = getMocksByType(mocks);
 
   restMocks.forEach(handleRestMock);
   graphQLMocks.forEach(handleGraphQLMock);
+  webSocketMocks.forEach(handleWebsocketMock);
 
   if (config?.allowXHRPassthrough) {
     XHRMock.use(proxy);
@@ -78,12 +77,19 @@ export const reduceAllMocksForScenario = (
 
   const mocks = defaultMocks.concat(scenarioMocks);
 
-  const initialHttpMocks = mocks.filter(
-    ({ method }) => method !== 'GRAPHQL'
-  ) as HttpMock[];
-  const initialGraphQlMocks = mocks.filter(
-    ({ method }) => method === 'GRAPHQL'
-  ) as GraphQLMock[];
+  const {
+    restMocks: initialHttpMocks,
+    graphQLMocks: initialGraphQlMocks,
+    webSocketMocks: initialWebsocketMocks,
+  } = getMocksByType(mocks);
+
+  const websocketMocksByUrl = initialWebsocketMocks.reduce<
+    Record
+  >((result, mock) => {
+    const { url } = mock;
+    result[url] = mock;
+    return result;
+  }, {});
 
   const httpMocksByUrlAndMethod = initialHttpMocks.reduce<
     Record
@@ -130,7 +136,9 @@ export const reduceAllMocksForScenario = (
     }
   ) as GraphQLMock[];
 
-  return (httpMocks as any).concat(graphQlMocks);
+  const websocketMocks = Object.values(websocketMocksByUrl);
+
+  return [...httpMocks, ...graphQlMocks, ...websocketMocks];
 };
 
 /**
@@ -281,8 +289,26 @@ function handleGraphQLMock({ url, operations }: GraphQLMock) {
   });
 }
 
+const handleWebsocketMock = ({ url, server }: WebSocketMock) => {
+  server(new MockServer(url));
+};
+
 /**
  * Adds delay (in ms) before resolving a promise.
  */
 const addDelay = (delay: number) =>
   new Promise((res) => setTimeout(res, delay));
+
+const getMocksByType = (mocks: Mock[]) => {
+  const restMocks = mocks.filter(
+    (m) => !['GRAPHQL', 'WEBSOCKET'].includes(m.method)
+  ) as HttpMock[];
+  const graphQLMocks = mocks.filter(
+    (m) => m.method === 'GRAPHQL'
+  ) as GraphQLMock[];
+
+  const webSocketMocks = mocks.filter(
+    (m) => m.method === 'WEBSOCKET'
+  ) as WebSocketMock[];
+  return { restMocks, graphQLMocks, webSocketMocks };
+};
diff --git a/src/types.ts b/src/types.ts
index 06271e1..2c48dde 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -3,6 +3,7 @@ export {
   injectMocks,
   reduceAllMocksForScenario,
 } from './mocks';
+import { Server as MockServer } from 'mock-socket';
 
 export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
 
@@ -27,6 +28,13 @@ export type GraphQLMock = {
   operations: Array;
 };
 
+export type WebSocketServerMock = (mockServer: MockServer) => void;
+export type WebSocketMock = {
+  url: string;
+  method: 'WEBSOCKET';
+  server: WebSocketServerMock;
+};
+
 export type Operation = {
   type: 'query' | 'mutation';
   operationName: string;
@@ -36,7 +44,7 @@ export type Operation = {
   delay?: number;
 };
 
-export type Mock = HttpMock | GraphQLMock;
+export type Mock = HttpMock | GraphQLMock | WebSocketMock;
 
 export type Scenarios = {
   default: Mock[];
diff --git a/yarn.lock b/yarn.lock
index 8c12ec6..3251c1c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3431,6 +3431,13 @@ mkdirp@1.x:
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
   integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
 
+mock-socket@^9.0.3:
+  version "9.0.3"
+  resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-9.0.3.tgz#4bc6d2aea33191e4fed5ec71f039e2bbeb95e414"
+  integrity sha512-SxIiD2yE/By79p3cNAAXyLQWTvEFNEzcAO7PH+DzRqKSFaplAPFjiQLmw8ofmpCsZf+Rhfn2/xCJagpdGmYdTw==
+  dependencies:
+    url-parse "^1.4.4"
+
 mri@^1.1.4:
   version "1.1.5"
   resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.5.tgz#ce21dba2c69f74a9b7cf8a1ec62307e089e223e0"
@@ -3918,6 +3925,11 @@ querystring@0.2.0, querystring@^0.2.0:
   resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
   integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
 
+querystringify@^2.1.1:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
+  integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
+
 react-is@^16.12.0:
   version "16.13.1"
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@@ -4101,6 +4113,11 @@ require-main-filename@^2.0.0:
   resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
   integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
 
+requires-port@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+  integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
+
 resolve-cwd@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
@@ -4739,6 +4756,14 @@ urix@^0.1.0:
   resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
   integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
 
+url-parse@^1.4.4:
+  version "1.5.3"
+  resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862"
+  integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==
+  dependencies:
+    querystringify "^2.1.1"
+    requires-port "^1.0.0"
+
 url@^0.11.0:
   version "0.11.0"
   resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"