依赖注入:同一功能的rest和默认功能参数?

时间:2018-12-12 22:49:16

标签: javascript testing dependency-injection

说我有一些这样的代码:

function a(...numbers) {
   return numbers.map(n => b(n)); 
}

function b(n) {
   return n+1; 
}

我一直在寻找可以像这样的代码进行测试的方法,特别是在不实际调用a的情况下测试b的功能。

一种选择是使用依赖注入,并将函数b作为参数传递。

即。

function a(...numbers, _b=b) {
   return numbers.map(n => _b(n)); 
}

但是,当然,rest运算符不允许我在最后提出一个论点。

而且我不想放在函数参数的第一位,因为开发人员必须每次都必须传递函数b或类似的东西,或者传递空值或类似的值。

有没有一种方法可以实现此功能?

2 个答案:

答案 0 :(得分:0)

rest参数只能作为函数接受的最后一个参数,它会捕获函数参数中未声明的所有argumet。实际上,您可以放下其余参数,然后传入一个数组

function a(numbers, _b = b) {
   return numbers.map(n => _b(n)); 
}

function b(n) {
   return n+1; 
}

console.log(a([1,2,3,4], f => f * 1));

答案 1 :(得分:0)

Function.prototype.bind()(有点)解决了这个问题!

//The convention we will use here is that developers shouldn't use the 
// _underscore methods in production. 

export const _a = function(_b, ...numbers) {
 return numbers.map(n => _b(n)); 
}; 

export const b = function(n) {
  return n+1; 
}

export const a = _a.bind(null, b); 

console.log(a(1,2,3)) //[2,3,4]

这还有一个优点,就是您向开发人员隐藏了注入的函数。

现在您将如何测试呢?

您必须测试_underscore方法,如下所示:

import { _a } from "../functions";

describe("_a", () => {

    it("_a(1,2,3) calls _b three times.", () => {
        const mockFn = jest.fn();
        const a = _a.bind(null, mockFn);

        a(1, 2, 3);

        expect(mockFn.mock.calls).toHaveLength(3);
    })

}); 

如果您有兴趣-我已经开始了Github repo with a more fleshed out example of this approach here

如果有人有一个比较整齐的方法-我都很高兴。