函数式javascript和RxJS中的依赖注入和模拟

pet*_*ing 7 javascript unit-testing functional-programming dependency-injection rxjs

我正在尝试使用RxJS和函数组合将用经典OO Javascript编写的库重写为更具功能性和反应性的方法.我已经开始使用以下两个易于测试的函数(我跳过了Observables的导入):

创建-connection.js

export default (amqplib, host) => Observable.fromPromise(amqplib.connect(host))
Run Code Online (Sandbox Code Playgroud)

创建-channel.js

export default connection => Observable.fromPromise(connection.createChannel())
Run Code Online (Sandbox Code Playgroud)

我要做的就是测试它们是注入amqplib或连接的模拟,并确保调用正确的方法,如下所示:

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');
    });
});
Run Code Online (Sandbox Code Playgroud)

所以现在我想将这两个函数放在一起:

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

export default ({ host }) => 
    createConnection(amqlib, host)
        .mergeMap(createChannel)
Run Code Online (Sandbox Code Playgroud)

然而,虽然这限制了我在测试时的选择,因为我无法注入amqplib的模拟.我也许可以将它作为依赖项添加到我的函数参数中,但这样我就必须在树中遍历并传递依赖关系,如果任何其他组合将要使用它.此外,我希望能够模拟createConnectioncreateChannel功能,甚至不必测试我之前测试过的相同行为,我是否意味着我必须将它们作为依赖项添加?

如果是这样,我可以在我的构造函数中有一个带有依赖项的工厂函数/类,然后使用某种形式的控制反转来管理它们并在必要时注入它们,但这实际上使我回到了我开始的面向对象方法.

我知道我可能做错了什么,但说实话,我发现零(null,nada)教程关于测试功能组合的功能性javascript(除非这不是一个,在这种情况下是什么).

mar*_*ian 0

您是否考虑过研究这些模拟包?特别rewire可能适合。

Proxyquire、rewire、SandboxedModule 和 Sinon:优缺点