如何使用Jasmine为私有方法编写Angular/TypeScript的单元测试 [英] How to write unit testing for Angular / TypeScript for private methods with Jasmine

查看:111
本文介绍了如何使用Jasmine为私有方法编写Angular/TypeScript的单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在angular 2中测试私有函数?

How do you test a private function in 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;
    }

}

我找到的解决方案

  1. 将测试代码本身放入闭包内,或将代码添加到闭包内,用于存储对外部作用域中现有对象上的局部变量的引用.

  1. Put the test code itself inside the closure or Add code inside the closure that stores references to the local variables on existing objects in the outer scope.

稍后使用工具删除测试代码. http://philipwalton.com/articles/how- to-unit-test-private-functions-in-javascript/

Later strip out the test code using a tool. http://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/

如果您有任何建议,请给我建议一个更好的方法来解决此问题?

Please suggest me a better way to solve this problem if you have done any?

PS

  1. 大多数类似问题的答案都不能解决问题,这就是为什么我要问这个问题

  1. Most of the answer for similar type of question like this one doesn't give a solution to problem, that's why I'm asking this question

大多数开发人员都说您不测试私有功能,但我不是说它们是对还是错,但是我的案例有必要测试私有功能.

Most of the developer say you Don’t test private functions but I don't say they are wrong or right, but there are necessities for my case to test private.

推荐答案

尽管您的目标是仅对公共API进行单元测试",这是一个很好的目标,但有时它似乎并不那么简单,您觉得自己是在损害API还是单元测试之间做出选择.您已经知道了这一点,因为这正是您要执行的操作,因此我将不再赘述. :)

I'm with you, even though it's a good goal to "only unit test the public API" there are times when it doesn't seem that simple and you feel you are choosing between compromising either the API or the unit-tests. You know this already, since that's exactly what you're asking to do, so I won't get into it. :)

在TypeScript中,我发现了一些用于进行单元测试的访问私有成员的方法.考虑这个课程:

In TypeScript I've discovered a few ways you can access private members for the sake of unit-testing. Consider this class:

class MyThing {

    private _name:string;
    private _count:number;

    constructor() {
        this.init("Test", 123);
    }

    private init(name:string, count:number){
        this._name = name;
        this._count = count;
    }

    public get name(){ return this._name; }

    public get count(){ return this._count; }

}

尽管TS使用privateprotectedpublic限制了对类成员的访问,但是编译后的JS没有私有成员,因为在JS中这不是问题.它仅用于TS编译器.为此:

Even though TS restricts access to class members using private, protected, public, the compiled JS has no private members, since this isn't a thing in JS. It's purely used for the TS compiler. Therefor:

  1. 您可以声明any并使编译器免于警告您有关访问限制的信息:

  1. You can assert to any and escape the compiler from warning you about access restrictions:

(thing as any)._name = "Unit Test";
(thing as any)._count = 123;
(thing as any).init("Unit Test", 123);

这种方法的问题在于,编译器根本不知道您在any的位置做什么,因此您不会得到所需的类型错误:

The problem with this approach is that the compiler simply has no idea what you are doing right of the any, so you don't get desired type errors:

(thing as any)._name = 123; // wrong, but no error
(thing as any)._count = "Unit Test"; // wrong, but no error
(thing as any).init(0, "123"); // wrong, but no error

这显然会使重构更加困难.

This will obviously make refactoring more difficult.

您可以使用数组访问([])来获取私有成员:

You can use array access ([]) to get at the private members:

thing["_name"] = "Unit Test";
thing["_count"] = 123;
thing["init"]("Unit Test", 123);

虽然看上去很时髦,但TSC实际上会像直接访问它们一样验证类型:

While it looks funky, TSC will actually validate the types as if you accessed them directly:

thing["_name"] = 123; // type error
thing["_count"] = "Unit Test"; // type error
thing["init"](0, "123"); // argument error

说实话,我不知道为什么会这样.这显然是,使您可以访问私人成员,而不会失去类型安全性.这正是我认为您要进行单元测试的目的.

To be honest I don't know why this works. This is apparently an intentional "escape hatch" to give you access to private members without losing type safety. This is exactly what I think you want for your unit-testing.

下面是一个了打字稿游乐场的工作实施例.

Here is a working example in the TypeScript Playground.

为TypeScript 2.6编辑

有些人喜欢的另一种选择是使用// @ts-ignore(

Another option that some like is to use // @ts-ignore (added in TS 2.6) which simply suppresses all errors on the following line:

// @ts-ignore
thing._name = "Unit Test";

问题是,它抑制了以下行中的所有错误:

The problem with this is, well, it suppresses all errors on the following line:

// @ts-ignore
thing._name(123).this.should.NOT.beAllowed("but it is") = window / {};

我个人认为@ts-ignore是一种代码气味,正如文档所说:

I personally consider @ts-ignore a code-smell, and as the docs say:

我们建议您非常少用. [强调原文]

we recommend you use this comments very sparingly. [emphasis original]

这篇关于如何使用Jasmine为私有方法编写Angular/TypeScript的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆