如何在angular 2中测试私有函数?
class FooBar {
private _status: number;
constructor( private foo : Bar ) {
this.initFooBar();
}
private initFooBar(){
this.foo.bar( "data" );
this._status = this.fooo.foo();
}
public get status(){
return this._status;
}
}
我找到了解决办法
将测试代码本身放在闭包中,或者在闭包中添加代码,以存储外部作用域中现有对象上局部变量的引用。
稍后使用工具提取测试代码。
http://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/
如果你做过这个问题,请给我一个更好的解决方法。
P.S
大多数类似类型的问题的答案都没有给出问题的解决方案,这就是我问这个问题的原因
大多数开发人员说不要测试私有函数,但我不会说它们是错的还是对的,但我的案例中有必要测试私有函数。
不要为私有方法编写测试。这就破坏了单元测试的意义。
您应该测试类的公共API
你不应该测试类的实现细节
例子
class SomeClass {
public addNumber(a: number, b: number) {
return a + b;
}
}
如果之后实现发生变化,但公共API的行为保持不变,则该方法的测试不需要更改。
class SomeClass {
public addNumber(a: number, b: number) {
return this.add(a, b);
}
private add(a: number, b: number) {
return a + b;
}
}
不要仅仅为了测试而将方法和属性设为公共。这通常意味着:
您正在尝试测试实现,而不是API(公共接口)。
您应该将所讨论的逻辑移到它自己的类中,以使测试更容易。
Aaron的答案是最好的,对我来说也很有用:)
我会给它投票,但遗憾的是我不能(失去声誉)。
我不得不说,测试私有方法是使用它们并在另一方面有干净代码的唯一方法。
例如:
class Something {
save(){
const data = this.getAllUserData()
if (this.validate(data))
this.sendRequest(data)
}
private getAllUserData () {...}
private validate(data) {...}
private sendRequest(data) {...}
}
不一次测试所有这些方法是很有意义的,因为我们需要模拟出那些私有方法,我们不能模拟出来,因为我们不能访问它们。这意味着我们需要对一个单元测试进行大量的配置,以将其作为一个整体进行测试。
这就是说,测试上述方法的所有依赖关系的最佳方法是端到端测试,因为这里需要集成测试,但如果您正在实践TDD(测试驱动开发),则端到端测试对您没有帮助,但测试任何方法都有帮助。
“不要测试私有方法”的重点实际上是像使用它的人那样测试类。
如果你有一个带有5个方法的公共API,你的类的任何消费者都可以使用这些方法,因此你应该测试它们。使用者不应该访问类的私有方法/属性,这意味着在公共公开功能保持不变的情况下,可以更改私有成员。
如果依赖内部可扩展功能,请使用protected而不是private。
注意protected仍然是一个公共API(!),只是使用方式不同。
class OverlyComplicatedCalculator {
public add(...numbers: number[]): number {
return this.calculate((a, b) => a + b, numbers);
}
// can't be used or tested via ".calculate()", but it is still part of your public API!
protected calculate(operation, operands) {
let result = operands[0];
for (let i = 1; i < operands.length; operands++) {
result = operation(result, operands[i]);
}
return result;
}
}
单元测试保护的属性与消费者使用它们的方式相同,通过子类化:
it('should be extensible via calculate()', () => {
class TestCalculator extends OverlyComplicatedCalculator {
public testWithArrays(array: any[]): any[] {
const concat = (a, b) => [].concat(a, b);
// tests the protected method
return this.calculate(concat, array);
}
}
let testCalc = new TestCalculator();
let result = testCalc.testWithArrays([1, 'two', 3]);
expect(result).toEqual([1, 'two', 3]);
});