samedi 26 août 2017

Generic test in TypeScript that asserts each property on a class has a value assigned

I have a TypeScript +2.4 project where I'm using Jest for my unit tests. The project has a lot of poco models, without a default value. For example:

export class Foo {
    public id: number
    public name: string;
    public when: Date;
}

Each of these models is mapped from raw json to this class. It is a requirement for my tests that all properties are assigned, e.g. have values. This leads to the following test that has to be written for all models:

test('Foo() should have its properties assigned', () => {
    const target: Foo = {
        id: 1001, name: 'whatever', when: new Date()
    };

    // manually assert each propertie here
    expect(target.id).toBeDefined();
    expect(target.name).toBeDefined();
    expect(target.when).toBeDefined();
}

To me, that's not so DRY to do for each test. Not to mention error prone and cumbersome. What I would like to do is create a helper that iterates through each property and asserts that it has a value assigned.

Example 1 - Object.keys
This example is incorrect because Object.keys only iterates through the already assigned properties, ignoring the non-set properties (and thus always is positive):

public static AssertAllPropertiesAreAssigned(target: object): void {
    Object.keys(target).forEach((key, index) => {
        expect(target[key]).toBeDefined();
});

Example 2 - Object.getOwnPropertyNames()
The same as example 1:

public static AssertAllPropertiesAreAssigned(target: object): void {
    Object.getOwnPropertyNames(target).forEach((name, index) => {
        expect(target[name]).toBeDefined();
});

Example 3 - Set default values
By assigning a default value to each poco, like null, I can make the earlier samples work. But I'd sure like to avoid that at all cost:

export class Foo {
    public id: number = null;
    public name: string = null;
    public when: Date = null;
}

The question: is there a way to create a helper that asserts that each property of my TypeScript poco object is actually assigned a value, in my test? Or, as an alternative, does Jest have some util for this?

There are similar questions on SO, but they are not related to asserting the values in a test. This makes this question, as far as I've looked around, differ from the others:

Also, I'm aware that the Javascript compiled output of my poco will probably leads to that the unset properties are simply not available:

var Foo = (function() {
    // nothing here...
}());

But with TypeScript's strong typing power and recent changes and/or Jest helpers, there might be some additional options to get this done?





Aucun commentaire:

Enregistrer un commentaire