Dependency injection and mocking in functional javascript and RxJS

Viewed 703

I am trying to rewrite a library written in classical OO Javascript into a more functional and reactive approach using RxJS and function composition. I have begun with following two, easily testable functions (I skipped import of Observables):

create-connection.js

export default (amqplib, host) => Observable.fromPromise(amqplib.connect(host))

create-channel.js

export default connection => Observable.fromPromise(connection.createChannel())

All I have to do to test them is to inject a mock of amqplib or connection and make sure right methods are being called, like so:

import createChannel from 'create-channel';

test('it should create channel', t => {
    const connection = { createChannel: () => {}};
    const connectionMock = sinon.mock(connection);

    connectionMock.expects('createChannel')
        .once()
        .resolves('test channel');

    return createChannel(connection).map(channel => {
        connectionMock.verify();
        t.is(channel, 'test channel');
    });
});

So now I would like to put the two functions together like so:

import amqplib from 'amqplib';
import { createConnection, createChannel } from './';

export default ({ host }) => 
    createConnection(amqlib, host)
        .mergeMap(createChannel)

However though this limits my options when it comes to testing because I cannot inject a mock of amqplib. I could perhaps add it to my function arguments as a dependency but that way I would have to traverse all the way up in a tree and pass dependencies around if any other composition is going to use it. Also I would like to be able to mock createConnection and createChannel functions without even having to test the same behaviour I tested before, would that I mean I would have to add them as dependencies too?

If so I could have a factory function/class with dependencies in my constructor and then use some form of inversion of control to manage them and inject them when necessary, however that essentially puts me back where I started which is Object Oriented approach.

I understand I am probably doing something wrong, but to be honest I found zero (null, nada) tutorials about testing functional javascript with function composition (unless this isn't one, in which case what is).

2 Answers
Related