testdouble.js
testdouble.js copied to clipboard
Feature: Compatibility with 'app-root-path'
When it comes to large codebases, it can be massively beneficial to grab libraries from the root resolution rather than relative path resolution ../../
There is an excellent library to assist with this for NodeJs but its not compatible with testdouble's .replace operation
https://www.npmjs.com/package/app-root-path
Would be great to see this compatibility so assist with a consistent resolution approach through projects.
As an example: users.js
// NPM Requires
const express = require('express')
// Library Requires
const users = require('./users')
// const users = reqlib('routes/example/users')
// Module Variables
module.exports = function (app) {
var route = express.Router()
// Mount route as "/users"
app.use('/users', route)
// Add a route that allows us to get a user by their username
route.get('/:username', function (req, res) {
var user = users.getByUsername(req.params.username)
console.log(user)
if (!user) {
res.status(404).json({
status: 'not ok',
data: null
})
} else {
res.json({
status: 'ok',
data: user
})
}
})
}
users.spec.js
// NPM Requires
const supertest = require('supertest')
const express = require('express')
const td = require('testdouble')
// Library Requires
const chai = reqlib('helpers/chai-setup')
// Module Variables
describe('GET /ping', function() {
const interaction = ['Mocked', 'Passthrough']
const isMockedLoop = [true, false]
isMockedLoop.forEach(function(isMocked) {
let app, request, route, users, usersTD
beforeEach(function() {
// Create an express application object
app = express()
// Get our router module, with a stubbed out users dependency
// we stub this out so we can control the results returned by
// the users module to ensure we execute all paths in our code
if (isMocked) {
users = td.replace('./users')
usersTD = users.getByUsername
// Setup generic returns for each td function
td.when(usersTD(td.matchers.anything())).thenReturn(null)
}
route = require('./user-route')
// route = reqlib('routes/example/user-route')
// Bind our application to
route(app)
// Get a supertest instance so we can make requests
request = supertest(app)
})
it(interaction[isMockedLoop.indexOf(isMocked)] + ': should respond with a 404 and a null', function() {
if (isMocked) {
// td.when(usersTD('nodejs')).thenReturn({
// username: 'test'
// })
} else {
// Skip test until the mocked function has been coded
this.skip()
}
return request
.get('/users/nodejs')
.expect(404)
.then((res) => {
td.verify(users.getByUsername(td.matchers.anything()))
})
})
it(interaction[isMockedLoop.indexOf(isMocked)] + ': should respond with 200 and a user object', function() {
console.log(isMocked)
if (isMocked) {
td.when(usersTD('nodejs')).thenReturn({
username: 'test'
})
} else {
// Skip test until the mocked function has been coded
this.skip()
}
return request
.get('/users/nodejs')
.expect(200)
.then((res) => {
td.verify(users.getByUsername(td.matchers.anything()))
})
})
afterEach(function() {
if (isMocked) {
td.reset()
}
})
})
})
app-root-path is enabled by including a global in the root of the call chain global.reqlib = require('app-root-path').require
when trying to use reqlib to load require td isn't called, even is absolute paths are used