Unit test a private method that uses request, pipe and stream using mocks
Asked Answered
H

1

8

I want to unit test the exported method in the code below. I want to mock the values in the private method to control the reject/resolves of the returned Promise. client is node-postgres object that is already connected to the database.

I know I can use proxyquire to stub out required libraries but how can I mock the chained methods .on('error', ...), .pipe(stream) and .on('end', ...) such that I can control the returned values.

Note the exported method shown is a simplification of the real one and exporting importDomain is not feasible.

const copyFrom = require('pg-copy-streams').from
const request = require('request')
const Promise = require('bluebird')

// private
function importDomain (client, domain) {
    return new Promise((resolve, reject) => {
    let stream = client.query(copyFrom(`COPY ${domain.table} FROM STDIN;`))

    let req = request(`${domain.url}`)
    req.on('error', reject)
    req.pipe(stream)
       .on('error', reject)
       .on('end', resolve)
  })
}

// public
module.exports = (client) => {
  let domain = someFunctionReturningDomain()
  importDomain(client, domain)
}
Hayman answered 3/3, 2017 at 21:21 Comment(0)
L
1

In order to unit test the function importDomain, you will need to mock request. It's required by your module so should be considered to be tested and working normally.

Since you provide the client as a parameter. Its query method and the stream returned is already under full control out of the module.

Simply by replacing req.pipe, you will be able to control what is passed to the stream your client created.

Limann answered 9/3, 2017 at 8:4 Comment(2)
How are the .on() tested? I'd like to see some code samples showing how this can be done.Hayman
When you mock request, implement it as a writable stream and write data to it while testing. see #33141512Dysgraphia

© 2022 - 2024 — McMap. All rights reserved.