testdouble.js icon indicating copy to clipboard operation
testdouble.js copied to clipboard

Feature: Compatibility with 'app-root-path'

Open keidrych opened this issue 8 years ago • 0 comments

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

keidrych avatar Sep 08 '17 04:09 keidrych