如何在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
大多数类似类型的问题的答案都没有给出问题的解决方案,这就是我问这个问题的原因
大多数开发人员说不要测试私有函数,但我不会说它们是错的还是对的,但我的案例中有必要测试私有函数。
我同意@toskv的观点:我不建议这么做:-)
但是如果你真的想测试你的私有方法,你可以意识到TypeScript的相应代码对应于构造函数原型的一个方法。这意味着它可以在运行时使用(然而您可能会有一些编译错误)。
例如:
export class FooBar {
private _status: number;
constructor( private foo : Bar ) {
this.initFooBar({});
}
private initFooBar(data){
this.foo.bar( data );
this._status = this.foo.foo();
}
}
将转化为:
(function(System) {(function(__moduleName){System.register([], function(exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var FooBar;
return {
setters:[],
execute: function() {
FooBar = (function () {
function FooBar(foo) {
this.foo = foo;
this.initFooBar({});
}
FooBar.prototype.initFooBar = function (data) {
this.foo.bar(data);
this._status = this.foo.foo();
};
return FooBar;
}());
exports_1("FooBar", FooBar);
}
}
})(System);
查看这个plunkr: https://plnkr.co/edit/calJCF?p=preview。
你可以调用私有方法!
如果您遇到以下错误:
expect(new FooBar(/*...*/).initFooBar()).toEqual(/*...*/)
// TS2341: Property 'initFooBar' is private and only accessible within class 'FooBar'
只需使用// @ts-ignore:
// @ts-ignore
expect(new FooBar(/*...*/).initFooBar()).toEqual(/*...*/)
感谢@Moff452的评论。你也可以这样写:
expect(new FooBar(/*...*/)['initFooBar']()).toEqual(/*...*/)
更新:
@ts-expect-error是@ts-ignore的更好选择。看到的:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#ts-ignore-or-ts-expect-error
不要为私有方法编写测试。这就破坏了单元测试的意义。
您应该测试类的公共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(公共接口)。
您应该将所讨论的逻辑移到它自己的类中,以使测试更容易。