Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing Typescript decorators

I have an application built on typescript with decorators for some convenience property assignments and wondering how I can go about writing unit tests for them.

 export function APIUrl() {
        return function (target: any, key: string) {
             let _value = target[key];

          function getter() {
            return _value;
          }

          function setter(newValue) {
            _value = getApiURL();
          }

          if (delete target[key]) {
            Object.defineProperty(target, key, {
                get: getter,
                set: setter
            });
          }
        };
    }

In a spec class I have,

 it("should return url string", ()=> {
   @APIUrl();
   let baseURL:string;

   expect(baseURL typeOf string).toBe(true)
 })
like image 400
Rjk Avatar asked Aug 24 '16 01:08

Rjk


People also ask

Should you use decorators in TypeScript?

Decorators provide a way to add both annotations and a meta-programming syntax for class declarations and members. Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript. NOTE Decorators are an experimental feature that may change in future releases.

How do I run a unit test in TypeScript?

For TypeScript, unit tests are run against the generated JavaScript code. In most TypeScript scenarios, you can debug a unit test by setting a breakpoint in TypeScript code, right-clicking a test in Test Explorer, and choosing Debug.

How do you write test cases for decorators?

Let's try to approach writing a test case for decorator as if we were writing test for regular function: we need to call using_email_address with certain input and assert that whatever happens inside of it produces expected output/result. This technique of writing tests is called “black box testing”.


2 Answers

Since decorators are just functions I would suggest to just test them like any other function. And only if you really need to, add one tests that shows how to use the decorator with a class/member/...

Here is an example such a test could look like:

import test from 'ava';
import { APIUrl } from './path';

const decorate = new APIUrl();

test.before(t => {
  let obj = { someProp: 'foo' };
  decorate(obj, 'someProp');
  t.context.foo = obj;
});

test('should return original value', t => {
  t.is(t.context.foo.someProp, 'foo');
});
like image 173
Sebastian Sebald Avatar answered Oct 27 '22 01:10

Sebastian Sebald


Another approach could be to setup some properties and/or methods that use your decorators and test their usage directly.

Note: decorators can only be used on class methods and members so you'd need to create a dummy class in your test.

Here's an example:

//Test Setup
class Test {

    @APIUrl()
    url: string;

    @AnotherDecorator()
    anotherFunction() {}

}


//Unit tests
describe('Decorator Tests', () => {
    it('should work', () => {
       const t = new Test();
       expect(t.url).toEqual("something");
       expect(t.anotherFunction()).toReturn("something else");
    });
}
like image 38
cs_pupil Avatar answered Oct 27 '22 01:10

cs_pupil