All the test is passing successfully but still the cypress test is generating token continuously.
cypress.config.js
const { defineConfig } = require("cypress");
const spauth = require("node-sp-auth");
let getLoginTest = async () => {
const username = "****#****.com";
const password = "******";
const pageUrl = "https://*****.sharepoint.com"
// Connect to SharePoint
const data = await spauth.getAuth(pageUrl, {
username: username,
password: password
});
return data;
};
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
on('task', {
// deconstruct the individual properties
async getLogin() {
try {
const res = await getLoginTest();
return res;
} catch (error) {
return error;
}
}
});
},
},
});
Below I have mentioned the tests case which I have created."Testspec.cy.js"
// <reference types="cypress" />
require('cypress-xpath')
describe('SharePoint Authentication', () => {
beforeEach(() => {
cy.task("getLogin").then(token => {
cy.visit({
method: "GET",
url: "https://*****.sharepoint.com/SitePages/Home.aspx",
headers: token.headers
});
});
});
it('SharePoint Authentication Test', () => {
cy.xpath('//*[contains(text(),"Customer Dashboard")]').should('be.visible');
cy.get('.alphabet > :nth-child(3)').click();
cy.contains('Leader').click();
});
});
Test Screen
Here is the screenshot of the cypress test
I'm trying to introduce a small change to an existing project without unit tests and decided I'd try to learn enough about nodejs and jest to include tests with my change. However, I cannot get mocks to work like I'd expect in, say, python. The project uses the "kubernetes-client" library from godaddy and tries to create a config object from the envvar "KUBECONFIG", like this:
// a few lines into server.js
// Instantiate Kubernetes client
const Client = require('kubernetes-client').Client
const config = require('kubernetes-client').config;
if (process.env.KUBECONFIG) {
client = new Client({
config: config.fromKubeconfig(config.loadKubeconfig(process.env.KUBECONFIG)),
version: '1.13'
});
}
else {
client = new Client({ config: config.getInCluster(), version: '1.9' });
}
In my testing environment, I don't want any API calls, so I'm trying to mock it out:
// __tests__/server.test.js
// Set up mocks at the top because of how server.js sets up k8s client
const k8sClient = require('kubernetes-client');
const narp = 'narp';
jest.mock('kubernetes-client', () => {
const noConfigmaps = jest.fn(() => {
throw narp;
});
const namespaces = jest.fn().mockReturnValue({
configmaps: jest.fn().mockReturnValue({
get: noConfigmaps
})
});
const addCustomResourceDefinition = jest.fn().mockReturnThis()
const mockClient = {
api: {
v1: {
namespaces
}
},
addCustomResourceDefinition: jest.fn().mockReturnThis(),
};
return {
Client: jest.fn(() => mockClient),
config: {
fromKubeconfig: jest.fn().mockReturnThis(),
loadKubeconfig: jest.fn().mockReturnThis(),
getInCluster: jest.fn().mockReturnThis()
},
};
});
const app = require('../server.js')
const supertest = require('supertest');
const requestWithSuperTest = supertest(app.app);
describe('Testing server.js', () => {
afterAll(() => {
app.server.close();
});
describe('Tests with k8s client throwing error when fetching configmaps', () => {
it("finds a resource's ingressGroup by name", () => {
var resource = {
"spec": {
"ingressClass": "foo",
"ingressTargetDNSName": "foo"
}
};
var ingressGroups = [
{
"ingressClass": "bar",
"hostName": "bar",
"name": "barName"
},
{
"ingressClass": "foo",
"hostName": "foo",
"name": "fooName"
}
];
expect(app.findMatchingIngressGroupForResource(resource, ingressGroups)).toBe("fooName");
});
it('GET /healthcheck should respond "Healthy"', async () => {
const resp = await requestWithSuperTest.get('/healthcheck');
console.log("Response in Testing Endpoints: " + JSON.stringify(resp));
expect(resp.status).toEqual(200);
expect(resp.type).toEqual(expect.stringContaining('text'));
expect(resp.text).toEqual('Healthy');
});
it('Tests getIngressGroups() rejects with error when it cannot get configmaps', async () => {
app.getIngressGroups()
.then()
.catch(error => {
expect(error).toEqual("Failed to fetch Ingress Groups: " + narp);
});
});
});
});
With this setup, the tests pass (although I suspect it's meaningless). If I try to move the mocks inside the describe or it block using a beforeEach function (or not) so that I can change the behavior to return mock data instead of throwing an error, I immediately get errors with the k8s client complaining it can't find my kubeconfig/clusterconfig:
$ npm run testj
> testj
> jest --detectOpenHandles
kubernetes-client deprecated require('kubernetes-client').config, use require('kubernetes-client/backends/request').config. server.js:45:44
kubernetes-client deprecated loadKubeconfig see https://github.com/godaddy/kubernetes-client/blob/master/merging-with-kubernetes.md#request-kubeconfig- server.js:49:42
FAIL __tests__/server.test.js
● Test suite failed to run
ENOENT: no such file or directory, open 'NOT_A_FILE'
44 | if (process.env.KUBECONFIG) {
45 | client = new Client({
> 46 | config: config.fromKubeconfig(config.loadKubeconfig(process.env.KUBECONFIG)),
| ^
47 | version: '1.13'
48 | });
49 | }
at node_modules/kubernetes-client/backends/request/config.js:335:37
at Array.map (<anonymous>)
at Object.loadKubeconfig (node_modules/kubernetes-client/backends/request/config.js:334:28)
at Object.eval [as loadKubeconfig] (eval at wrapfunction (node_modules/kubernetes-client/node_modules/depd/index.js:425:22), <anonymous>:5:11)
at Object.<anonymous> (server.js:46:46)
If anybody has run into this kind of behavior before or sees some obviously-wrong lines, I'd really appreciate any tips or information. Thanks!
I had to change a few things to get this working:
jest.doMock() instead of jest.mock()
use of let app inside the describe block instead of const app at module-scope
a beforeEach() which calls jest.resetModules()
an afterEach() which calls app.close()
in the it block which overrides the mock(s), explicitly call jest.resetModules() before overriding
in the it block which overrides the mock(s), call app.close() and re-initialize app before invoking the actual function-under-test/expect
Resulting test file:
// Set up mocks at the top because of how server.js sets up k8s client
const k8sClient = require('kubernetes-client');
const supertest = require('supertest');
const narp = 'narp';
describe('Testing server.js', () => {
let app;
let requestWithSuperTest;
beforeEach(() => {
jest.resetModules();
jest.doMock('kubernetes-client', () => {
const noConfigmaps = jest.fn(() => {
throw narp;
});
const namespaces = jest.fn().mockReturnValue({
configmaps: jest.fn().mockReturnValue({
get: noConfigmaps
})
});
const addCustomResourceDefinition = jest.fn().mockReturnThis()
const mockClient = {
api: {
v1: {
namespaces
}
},
addCustomResourceDefinition: jest.fn().mockReturnThis(),
};
return {
Client: jest.fn(() => mockClient),
config: {
fromKubeconfig: jest.fn().mockReturnThis(),
loadKubeconfig: jest.fn().mockReturnThis(),
getInCluster: jest.fn().mockReturnThis()
},
};
});
app = require('../server.js');
requestWithSuperTest = supertest(app.app);
});
afterEach(() => {
app.server.close();
});
it("finds a Resource's ingressGroup by name", () => {
var resource = {
"spec": {
"ingressClass": "foo",
"ingressTargetDNSName": "foo"
}
};
var ingressGroups = [
{
"ingressClass": "bar",
"hostName": "bar",
"name": "barName"
},
{
"ingressClass": "foo",
"hostName": "foo",
"name": "fooName"
}
];
expect(app.findMatchingIngressGroupForResource(resource, ingressGroups)).toBe("fooName");
});
it('GET /healthcheck should respond "Healthy"', async () => {
const resp = await requestWithSuperTest.get('/healthcheck');
console.log("Response in Testing Endpoints: " + JSON.stringify(resp));
expect(resp.status).toEqual(200);
expect(resp.type).toEqual(expect.stringContaining('text'));
expect(resp.text).toEqual('Healthy');
});
it('Tests getIngressGroups() rejects with error when it cannot get configmaps', async () => {
expect.assertions(1);
await app.getIngressGroups()
.catch(error => {
expect(error).toEqual("Failed to fetch Ingress Groups: " + narp);
});
});
it('Tests getIngressGroups() succeeds when it gets configmaps', async () => {
expect.assertions(1);
jest.resetModules();
jest.doMock('kubernetes-client', () => {
const noConfigmaps = jest.fn(() => {
console.log('Attempted to get mocked configmaps');
return Promise.resolve({
body: {
items: []
}
});
});
const namespaces = jest.fn().mockReturnValue({
configmaps: jest.fn().mockReturnValue({
get: noConfigmaps
})
});
const addCustomResourceDefinition = jest.fn().mockReturnThis()
const mockClient = {
api: {
v1: {
namespaces
}
},
addCustomResourceDefinition: jest.fn().mockReturnThis(),
};
return {
Client: jest.fn(() => mockClient),
config: {
fromKubeconfig: jest.fn().mockReturnThis(),
loadKubeconfig: jest.fn().mockReturnThis(),
getInCluster: jest.fn().mockReturnThis()
},
};
});
app.server.close();
app = require('../server.js');
await app.getIngressGroups()
.then(result => {
expect(result).toEqual([])
});
});
});
Our Prisma setup is as follows:
// server/database/prisma.ts
import { Prisma } from 'database/generated/prisma-client';
const client = new Prisma({
endpoint: PRISMA_ENDPOINT,
secret: PRISMA_SECRET,
debug: PRISMA_DEBUG,
});
// Add a proxy 'middleware' to the Prisma client to record query execution time
const prismaProxy = new Proxy(client, {
get(client, endpoint) {
const endTimer = metrics.prisma_call_duration_seconds.startTimer({ endpoint });
return function (...args) {
const result: Prisma = client[endpoint](...args);
endTimer();
return result;
};
},
});
export const prisma = prismaProxy;
I then have a utility that uses prisma that I would like to test:
// utils.ts
import { prisma } from 'database/prisma';
export const myFunc = async () => {
const result = await prisma.items();
if (items && items.length > 0) {
return true;
}
return false;
};
How do I mock prisma in a test? In Jest 26, this worked:
// utils.test.ts
jest.mock('server/database/prisma');
import { prisma } from 'server/database/prisma';
import { myFunc } from 'server/utils';
describe.only('my test', () => {
beforeAll(() => {
prisma.items.mockImplementation(() =>
Promise.resolve([
{
foo: 'bar',
},
])
);
});
test('it works', async () => {
const items = await myFunc();
expect(items).toBeTruthy();
});
});
This no longer works in Jest 27 it seems. Having made no changes except upgrading Jest from v26 -> v27 the mocks no longer seem to take hold.
What is the proper way to mock prisma here?
I'm New to unit test and trying to test my controller method.my project architecture design is as follow
Controller->Service->Model.
My test scenarios :
Pass correct parameters to controller method and test success response
Pass Invalid parameters to controller method and test error response
When i going to test scenario 1 ,according to my understanding i want to mock my programService and it return values.I have write test as follow and got errors.
I would really appreciate some one can fix this
ProgramsController.js
const ProgramService = require('../../services/program/programService');
class ProgramsController {
constructor() {
this.programService = new ProgramService();
}
async subscribe(req, res) {
try {
const { userId, uuid, msisdn, body: { programId } } = req;
const data = { userId, programId, msisdn, uuid }
const subscribe = await this.programService.subscribeUser(data);
res.json({
status: true,
message: 'Success',
friendly_message: constant.MSG.SUBSCRIPTION,
data: subscribe
})
} catch (error) {
res.status(500)
.json({
status: false,
message: 'Fail',
friendly_message: constant.MSG.SUBSCRIPTION_FAIL
})
}
}
}
ProgramService.js
class ProgramService {
constructor() {
this.subscriber = new Subscriber();
this.subsciberProgram = new SubsciberProgram()
}
async subscribeUser(data) {
try {
const { msisdn, userId, programId, uuid } = data;
...
return subscribedData;
} catch (error) {
throw error;
}
}
}
module.exports = ProgramService;
test.spec.js
const ProgramsService = require('../src/services/program/programService')
const ProgramsController = require('../src/controllers/programs/programsController')
const programController = new ProgramsController()
const programsService = new ProgramsService()
beforeAll(() => {
db.sequelize.sync({ force: true }).then(() => { });
});
const mockRequest = (userId, uuid, msisdn, body) => ({
userId,
uuid,
msisdn,
body,
});
const mockResponse = () => {
const res = {};
res.status = jest.fn().mockReturnValue(res);
res.json = jest.fn().mockReturnValue(res);
return res;
};
const serviceRecord = { userId: 1, programId: 1, msisdn: '56768382967', uuid: '46651a19-3ef1-4149-818e-9bd8a5f359ef' };
const fakeServiceReturn = { program_id: 1, amount: 5, no_of_questions: 10 }
describe('Subscribe', () => {
test('should return 200', async () => {
const req = mockRequest(
1,
'56768382967',
'46651a19-3ef1-4149-818e-9bd8a5f359ef',
{ 'programId': 1 }
);
const res = mockResponse();
const spy = jest.spyOn(programsService, 'subscribeUser').mockImplementation(() => serviceRecord);
await programController.subscribe(req, res);
expect(programsService.subscribeUser()).toHaveBeenCalledWith(fakeServiceReturn);
expect(res.status).toHaveBeenCalledWith(500);
expect(res.json).toHaveBeenCalledWith({
status: true,
message: 'Success',
friendly_message: 'successfull get data',
data : { program_id: 1, amount: 5, no_of_questions: 10 }
});
spy.mockRestore();
});
});
how can i mock programService.subscribeUser and test success response?
This mock should return a promise:
jest.spyOn(programsService, 'subscribeUser').mockImplementation(() => Promise.resolve(serviceRecord));
I am creating an API using Node but am struggling to understand how to properly Unit test the API. The API itself uses Express and Mongo (with Mongoose).
So far I have been able to create Integration tests for end to end testing of the API endpoints themselves. I have used supertest, mocha and chai for the integration tests along with dotenv to use a test database when running it. The npm test script sets the environment to test before the integration tests run. It works excellently.
But I would like to also create Unit Tests for various components such as the controller functions.
I'm keen to use Sinon for the Unit Tests but I'm struggling to know what next steps to take.
I'll detail a genericised version of the API rewritten to be everybody's favourite Todos.
The app has the following directory structure:
api
|- todo
| |- controller.js
| |- model.js
| |- routes.js
| |- serializer.js
|- test
| |- integration
| | |- todos.js
| |- unit
| | |- todos.js
|- index.js
|- package.json
package.json
{
"name": "todos",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"doc": "docs"
},
"scripts": {
"test": "mocha test/unit --recursive",
"test-int": "NODE_ENV=test mocha test/integration --recursive"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.15.0",
"express": "^4.13.4",
"jsonapi-serializer": "^3.1.0",
"mongoose": "^4.4.13"
},
"devDependencies": {
"chai": "^3.5.0",
"mocha": "^2.4.5",
"sinon": "^1.17.4",
"sinon-as-promised": "^4.0.0",
"sinon-mongoose": "^1.2.1",
"supertest": "^1.2.0"
}
}
index.js
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
// Configs
// I really use 'dotenv' package to set config based on environment.
// removed and defaults put in place for brevity
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
// Database
mongoose.connect('mongodb://localhost/todosapi');
//Middleware
app.set('port', 3000);
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// Routers
var todosRouter = require('./api/todos/routes');
app.use('/todos', todosRouter);
app.listen(app.get('port'), function() {
console.log('App now running on http://localhost:' + app.get('port'));
});
module.exports = app;
serializer.js
(This purely takes the output from Mongo and serializes it into JsonAPI format. So it is a bit superfluous to this example but I left it in as it is something I currently make use of in the api.)
'use strict';
var JSONAPISerializer = require('jsonapi-serializer').Serializer;
module.exports = new JSONAPISerializer('todos', {
attributes: ['title', '_user']
,
_user: {
ref: 'id',
attributes: ['username']
}
});
routes.js
var router = require('express').Router();
var controller = require('./controller');
router.route('/')
.get(controller.getAll)
.post(controller.create);
router.route('/:id')
.get(controller.getOne)
.put(controller.update)
.delete(controller.delete);
module.exports = router;
model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var todoSchema = new Schema({
title: {
type: String
},
_user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
});
module.exports = mongoose.model('Todo', todoSchema);
controller.js
var Todo = require('./model');
var TodoSerializer = require('./serializer');
module.exports = {
getAll: function(req, res, next) {
Todo.find({})
.populate('_user', '-password')
.then(function(data) {
var todoJson = TodoSerializer.serialize(data);
res.json(todoJson);
}, function(err) {
next(err);
});
},
getOne: function(req, res, next) {
// I use passport for handling User authentication so assume the user._id is set at this point
Todo.findOne({'_id': req.params.id, '_user': req.user._id})
.populate('_user', '-password')
.then(function(todo) {
if (!todo) {
next(new Error('No todo item found.'));
} else {
var todoJson = TodoSerializer.serialize(todo);
return res.json(todoJson);
}
}, function(err) {
next(err);
});
},
create: function(req, res, next) {
// ...
},
update: function(req, res, next) {
// ...
},
delete: function(req, res, next) {
// ...
}
};
test/unit/todos.js
var mocha = require('mocha');
var sinon = require('sinon');
require('sinon-as-promised');
require('sinon-mongoose');
var expect = require('chai').expect;
var app = require('../../index');
var TodosModel = require('../../api/todos/model');
describe('Routes: Todos', function() {
it('getAllTodos', function (done) {
// What goes here?
});
it('getOneTodoForUser', function (done) {
// What goes here?
});
});
Now I don't want to test the routes themselves (I do that in the Integration Tests not detailed here).
My current thinking is that the next best thing is to actually unit test controller.getAll or controller.getOne functions. And then to Mock the calls to Mongo via Mongoose using Sinon stubs.
But I have no idea what to do next despite having read the sinon docs :/
Questions
How do I test controller functions if it requires req, res, next as parameters?
Do I move the model's find and populate (currently in the Controller function) into todoSchema.static functions?
How to mock the populate function to do a Mongoose JOIN?
Basically what goes into test/unit/todos.js to get the above in a solid Unit Test state :/
The end goal is to run mocha test/unit and have it unit test the various parts of that API section
Hi I've created some test for you to understand how to use mocks.
Full example github/nodejs_unit_tests_example
controller.test.js
const proxyquire = require('proxyquire')
const sinon = require('sinon')
const faker = require('faker')
const assert = require('chai').assert
describe('todo/controller', () => {
describe('controller', () => {
let mdl
let modelStub, serializerStub, populateMethodStub, fakeData
let fakeSerializedData, fakeError
let mongoResponse
before(() => {
fakeData = faker.helpers.createTransaction()
fakeError = faker.lorem.word()
populateMethodStub = {
populate: sinon.stub().callsFake(() => mongoResponse)
}
modelStub = {
find: sinon.stub().callsFake(() => {
return populateMethodStub
}),
findOne: sinon.stub().callsFake(() => {
return populateMethodStub
})
}
fakeSerializedData = faker.helpers.createTransaction()
serializerStub = {
serialize: sinon.stub().callsFake(() => {
return fakeSerializedData
})
}
mdl = proxyquire('../todo/controller.js',
{
'./model': modelStub,
'./serializer': serializerStub
}
)
})
beforeEach(() => {
modelStub.find.resetHistory()
modelStub.findOne.resetHistory()
populateMethodStub.populate.resetHistory()
serializerStub.serialize.resetHistory()
})
describe('getAll', () => {
it('should return serialized search result from mongodb', (done) => {
let resolveFn
let fakeCallback = new Promise((res, rej) => {
resolveFn = res
})
mongoResponse = Promise.resolve(fakeData)
let fakeRes = {
json: sinon.stub().callsFake(() => {
resolveFn()
})
}
mdl.getAll(null, fakeRes, null)
fakeCallback.then(() => {
sinon.assert.calledOnce(modelStub.find)
sinon.assert.calledWith(modelStub.find, {})
sinon.assert.calledOnce(populateMethodStub.populate)
sinon.assert.calledWith(populateMethodStub.populate, '_user', '-password')
sinon.assert.calledOnce(serializerStub.serialize)
sinon.assert.calledWith(serializerStub.serialize, fakeData)
sinon.assert.calledOnce(fakeRes.json)
sinon.assert.calledWith(fakeRes.json, fakeSerializedData)
done()
}).catch(done)
})
it('should call next callback if mongo db return exception', (done) => {
let fakeCallback = (err) => {
assert.equal(fakeError, err)
done()
}
mongoResponse = Promise.reject(fakeError)
let fakeRes = sinon.mock()
mdl.getAll(null, fakeRes, fakeCallback)
})
})
describe('getOne', () => {
it('should return serialized search result from mongodb', (done) => {
let resolveFn
let fakeCallback = new Promise((res, rej) => {
resolveFn = res
})
mongoResponse = Promise.resolve(fakeData)
let fakeRes = {
json: sinon.stub().callsFake(() => {
resolveFn()
})
}
let fakeReq = {
params: {
id: faker.random.number()
},
user: {
_id: faker.random.number()
}
}
let findParams = {
'_id': fakeReq.params.id,
'_user': fakeReq.user._id
}
mdl.getOne(fakeReq, fakeRes, null)
fakeCallback.then(() => {
sinon.assert.calledOnce(modelStub.findOne)
sinon.assert.calledWith(modelStub.findOne, findParams)
sinon.assert.calledOnce(populateMethodStub.populate)
sinon.assert.calledWith(populateMethodStub.populate, '_user', '-password')
sinon.assert.calledOnce(serializerStub.serialize)
sinon.assert.calledWith(serializerStub.serialize, fakeData)
sinon.assert.calledOnce(fakeRes.json)
sinon.assert.calledWith(fakeRes.json, fakeSerializedData)
done()
}).catch(done)
})
it('should call next callback if mongodb return exception', (done) => {
let fakeReq = {
params: {
id: faker.random.number()
},
user: {
_id: faker.random.number()
}
}
let fakeCallback = (err) => {
assert.equal(fakeError, err)
done()
}
mongoResponse = Promise.reject(fakeError)
let fakeRes = sinon.mock()
mdl.getOne(fakeReq, fakeRes, fakeCallback)
})
it('should call next callback with error if mongodb return empty result', (done) => {
let fakeReq = {
params: {
id: faker.random.number()
},
user: {
_id: faker.random.number()
}
}
let expectedError = new Error('No todo item found.')
let fakeCallback = (err) => {
assert.equal(expectedError.message, err.message)
done()
}
mongoResponse = Promise.resolve(null)
let fakeRes = sinon.mock()
mdl.getOne(fakeReq, fakeRes, fakeCallback)
})
})
})
})
model.test.js
const proxyquire = require('proxyquire')
const sinon = require('sinon')
const faker = require('faker')
describe('todo/model', () => {
describe('todo schema', () => {
let mongooseStub, SchemaConstructorSpy
let ObjectIdFake, mongooseModelSpy, SchemaSpy
before(() => {
ObjectIdFake = faker.lorem.word()
SchemaConstructorSpy = sinon.spy()
SchemaSpy = sinon.spy()
class SchemaStub {
constructor(...args) {
SchemaConstructorSpy(...args)
return SchemaSpy
}
}
SchemaStub.Types = {
ObjectId: ObjectIdFake
}
mongooseModelSpy = sinon.spy()
mongooseStub = {
"Schema": SchemaStub,
"model": mongooseModelSpy
}
proxyquire('../todo/model.js',
{
'mongoose': mongooseStub
}
)
})
it('should return new Todo model by schema', () => {
let todoSchema = {
title: {
type: String
},
_user: {
type: ObjectIdFake,
ref: 'User'
}
}
sinon.assert.calledOnce(SchemaConstructorSpy)
sinon.assert.calledWith(SchemaConstructorSpy, todoSchema)
sinon.assert.calledOnce(mongooseModelSpy)
sinon.assert.calledWith(mongooseModelSpy, 'Todo', SchemaSpy)
})
})
})
routes.test.js
const proxyquire = require('proxyquire')
const sinon = require('sinon')
const faker = require('faker')
describe('todo/routes', () => {
describe('router', () => {
let expressStub, controllerStub, RouterStub, rootRouteStub, idRouterStub
before(() => {
rootRouteStub = {
"get": sinon.stub().callsFake(() => rootRouteStub),
"post": sinon.stub().callsFake(() => rootRouteStub)
}
idRouterStub = {
"get": sinon.stub().callsFake(() => idRouterStub),
"put": sinon.stub().callsFake(() => idRouterStub),
"delete": sinon.stub().callsFake(() => idRouterStub)
}
RouterStub = {
route: sinon.stub().callsFake((route) => {
if (route === '/:id') {
return idRouterStub
}
return rootRouteStub
})
}
expressStub = {
Router: sinon.stub().returns(RouterStub)
}
controllerStub = {
getAll: sinon.mock(),
create: sinon.mock(),
getOne: sinon.mock(),
update: sinon.mock(),
delete: sinon.mock()
}
proxyquire('../todo/routes.js',
{
'express': expressStub,
'./controller': controllerStub
}
)
})
it('should map root get router with getAll controller', () => {
sinon.assert.calledWith(RouterStub.route, '/')
sinon.assert.calledWith(rootRouteStub.get, controllerStub.getAll)
})
it('should map root post router with create controller', () => {
sinon.assert.calledWith(RouterStub.route, '/')
sinon.assert.calledWith(rootRouteStub.post, controllerStub.create)
})
it('should map /:id get router with getOne controller', () => {
sinon.assert.calledWith(RouterStub.route, '/:id')
sinon.assert.calledWith(idRouterStub.get, controllerStub.getOne)
})
it('should map /:id put router with update controller', () => {
sinon.assert.calledWith(RouterStub.route, '/:id')
sinon.assert.calledWith(idRouterStub.put, controllerStub.update)
})
it('should map /:id delete router with delete controller', () => {
sinon.assert.calledWith(RouterStub.route, '/:id')
sinon.assert.calledWith(idRouterStub.delete, controllerStub.delete)
})
})
})
serializer.test.js
const proxyquire = require('proxyquire')
const sinon = require('sinon')
describe('todo/serializer', () => {
describe('json serializer', () => {
let JSONAPISerializerStub, SerializerConstructorSpy
before(() => {
SerializerConstructorSpy = sinon.spy()
class SerializerStub {
constructor(...args) {
SerializerConstructorSpy(...args)
}
}
JSONAPISerializerStub = {
Serializer: SerializerStub
}
proxyquire('../todo/serializer.js',
{
'jsonapi-serializer': JSONAPISerializerStub
}
)
})
it('should return new instance of Serializer', () => {
let schema = {
attributes: ['title', '_user']
,
_user: {
ref: 'id',
attributes: ['username']
}
}
sinon.assert.calledOnce(SerializerConstructorSpy)
sinon.assert.calledWith(SerializerConstructorSpy, 'todos', schema)
})
})
})