fake-spotify-api v0.3.2
Fake Spotify API
A fake version of the Spotify API to allow:
- Testing without logging in to a real Spotify account (e.g. Automated testing as part of a CI/CD pipeline)
- Testing error cases easily (e.g. User no longer exists, token expired)
Usage
Install
You'll need npm installed. Run npm install
.
Use in Chai tests
Run npm install chai --save-dev
and npm install chai-http --save dev
. You can then run the app as part of your tests using:
import chai from 'chai';
import chaiHttp from 'chai-http';
import { fakeSpotifyApi } from 'fake-spotify-api';
chai.use(chaiHttp);
const request = chai.request;
describe('Some API', () => {
let server: ChaiHttp.Agent;
beforeEach(async () => {
// Startup a server using the Fake Spotify API. Use the agent so that we can use the sp_ac cookie created in signup to automatically authorize
server = request.agent(fakeSpotifyApi).keepOpen();
// Create a user. Note that this is not possible with the real Spotify API - you'd have to go through the signup process on the website.
await server.post('/signup').type('form').send({
display_name: 'Test',
email: 'test@example.com',
password: 'secret',
}); // You can use the response to this to get the user ID
// Call the authorize endpoint, which replies with a redirect to the supplied location, adding a the token details.
await server.get(`/authorize`).query({
client_id: '1',
redirect_uri: encodeURIComponent('http://localhost/'),
response_type: 'token',
}).redirects(0); // You can use the headers.location property of the response to get the token_type and access_token
});
// ...Add your tests here
afterEach(async () => {
// Shutdown the server so that we don't leave lots of these lying around
server.close();
});
});
See the end2end tests folder for examples.
As an application
Run npm start
.
For environment variables see .env
Endpoints
There are two types of endpoint:
- Spotify - Ones that the real Spotify API provides (e.g. GET /v1/me/playlists)
- Helper - Ones that the real Spotify API does not provide (e.g. POST /signup). These make it easier to test edge cases and create standalone tests.
You should be careful not use the helper endpoints outside of your tests.
Isn't there already a mock of the Spotify API?
All I've found is:
- https://github.com/0xNF/mockify - This doesn't yet implement any of the Spotify API.
Is it a mock, stub, spy, dummy, service virtualisation, fake, etc?
There are lots of different definitions for these. I've used the one from https://martinfowler.com/articles/mocksArentStubs.html
Limitations
Alot.
- Only implements the authorize endpoint and some of the playlist and user APIs.
- Does not use scopes provided in /authorize
- Unable to set default token expiry time for a user
- Unable to say a user will reject a authorization request
- Does not persist data outside of memory
Development
IDE
I've used vscode with the following plugins:
- DotENV
- Git History
- Mocha sidebar
- npm
- Prettier
- Switch to test
- TSLint
- TypeScript Hero
And the following in my User Settings json:
"createTest.srcFolder": "src",
"createTest.testFolder": "tests/unit",
"createTest.testFileExtension": ".spec.ts",
"createTest.testFileTemplate": [
"import ${moduleName} from '${modulePath}';",
"import { expect } from 'chai';",
"",
"describe('${moduleName}', () => {",
" it('does something', () => {",
" ",
" });",
"});"
],
"mocha.requires": ["ts-node/register"],
"mocha.files.glob": "./tests/**/*.spec.ts",
"javascript.preferences.quoteStyle": "single",
"prettier.singleQuote": true,
"prettier.tabWidth": 2,
"prettier.trailingComma": "es5",
"prettier.tslintIntegration": true,
"typescript.preferences.quoteStyle": "single",
"typescriptHero.imports.organizeOnSave": true,
"editor.tabSize": 2
Dependencies
Dev and production
- body-parser - How to parse the body of requests
- cookie-parser - Easy access to cookies from express
- dotenv - Set environment variables locally
- express - Minimal web framework
- express-joi-validation - Add middleware to express to validate calls to the API
- inversify - Dependency injection
- inversify-express-utils - Dependency injection plugged in to express.
- joi - Easy to code validation
- reflect-metadata - Used by inversify to add meta data to classes/functions
- uuid - Generate UUIDs
Dev-only
- chai - Testing library
- chai-http - Plugin for Chai to allow a server to be started and tested against.
- env-test - Automatically make tests run with
process.env.NODE_ENV = "test"
- mocha - Testing framework
- mocha-parallel-tests - Allow each test file to be run in parallel to lower total test time.
- nodemon - Monitor files for changes and automatically rebuild the project
- ts-lint - Make sure Typescript is formatted correctly for good readability and code that is less error prone.
- ts-node - Run node without having to compile to JS each time (works well with nodemon)
- tslint - See ts-lint above. Can't remember why I've installed both of these
- typescript - Add types to Javascript. Less error-prone and easier to work with (helps the IDE out with auto-completion)
Getting started
The best place to start is in the src/controllers folder. This is where incoming requests are handled.
Testing
Run npm run test
to run all the tests
Watch
Run npm run watch
to run the application and watch for changes in source files, which will be automatically built in to the application.
Notes
- Add
/* tslint:disable:no-unused-expression */
to the top of test files. I've tried to disable this for test files but failed. I tried: