Search code examples
typescriptdecorator

Type Error when unit testing class decorator


I have a task to implement the class decorator to add the “identify“ class method which returns a class name with the information passed in the decorator.
For example :

@identifier('example')
    class Test {}
    
    const test = new Test();
    console.log(test['identify']()); // Test-example  

It gives me the expected result when i console log, the class name and the string in brackets are showed.The main problem is when i run test units :

describe('identifier', () => {
    it('should return Test-example from identify', () => {
        @identifier('example')
        class Test {}
        const test = new Test();
        assert.strictEqual(test['identify'](), 'Test-example');
    });

    it('should return ClassA-prototype from identify', () => {
        @identifier('prototype')
        class ClassA {}
        const test = new ClassA();
        assert.strictEqual(test['identify'](), 'ClassA-prototype');
    })
});  

Decorator implementation :
Method 1 :

function identifier(...args: any): ClassDecorator {
    return function <TFunction extends Function>(
        target: TFunction
    ): TFunction | any {
        return target.name + "-" + args;
    };
}  

Method 2:

function identifier(passedInformation: string): any {
    return function (target) {
        return target.name + "-" + passedInformation;
    };
}  

Both functions are good i think,but both give me the same errors in junit.xml :

<testcase name="identifier should return Test-example from identify" time="0.0000" classname="should return Test-example from identify">
      <failure message="" type="TypeError"><![CDATA[TypeError: 
    at DecorateConstructor (node_modules\reflect-metadata\Reflect.js:544:31)
    at Object.decorate (node_modules\reflect-metadata\Reflect.js:130:24)
    at __decorate (test\index.ts:4:92)
    at C:\Users\artio\Desktop\6 Decorators\decorators\test\index.ts:81:20
    at Context.<anonymous> (test\index.ts:85:10)
    at processImmediate (internal/timers.js:439:21)]]></failure>
    </testcase>
    <testcase name="identifier should return ClassA-prototype from identify" time="0.0000" classname="should return ClassA-prototype from identify">
      <failure message="" type="TypeError"><![CDATA[TypeError: 
    at DecorateConstructor (node_modules\reflect-metadata\Reflect.js:544:31)
    at Object.decorate (node_modules\reflect-metadata\Reflect.js:130:24)
    at __decorate (test\index.ts:4:92)
    at C:\Users\artio\Desktop\6 Decorators\decorators\test\index.ts:93:22
    at Context.<anonymous> (test\index.ts:97:10)
    at processImmediate (internal/timers.js:439:21)]]></failure>
    </testcase>  

Does anyone know what is the problem and how can i solve it? I cant pass the task because of these errors ... to mention,unit tests i can not modify,only the functions.


Solution

  • So,i managed the error and modified a little the function and came up with this :

    function identifier(...args: any): ClassDecorator {
        return function <TFunction extends Function>(
            target: TFunction
        ): TFunction | any {
            var identify = target.prototype.identify;
            Object.defineProperty(target.prototype, 'identify', {
                value: function() {
                    return target.name + "-" + args;
                }
            });
            return identify;
        };
    }
    

    I did the identify method like the task needed and then returned it,no errors at unit tests and at run time,perfect.