2017-08-26 25 views
0

我有一个TypeScript +2.4项目,我用我的单元测试Jest。该项目有很多poco模型,没有默认值。例如:在TypeScript中的通用测试,声明每个类的属性有一个值分配

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

这些模型中的每一个都从原始json映射到这个类。我的测试要求分配所有的属性,例如有价值。这导致下面的测试必须写入所有型号:

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(); 
} 

对我来说,这不是每个测试干的。更不用说容易出错和麻烦了。我想要做的是创建一个帮助器,遍历每个属性并声明它有一个赋值。

实施例1 - Object.keys
该实施例不正确,因为Object.keys只有通过已经分配的属性迭代,忽略非集属性(和因此总是为正):

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

实施例2 - Object.getOwnPropertyNames()
同实施例1:

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

例3 - 设置默认值
通过指定一个默认值各POCO,像null,我可以让之前的抽样工作。但我确实希望避免不惜一切代价:

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

问题:是有办法创造断言我的打字稿POCO对象的每个属性实际上是赋值一个帮手,在我的测试?或者,作为替代方案,Jest是否有这个用途?

在SO上也有类似的问题,但它们与在测试中断言值无关。这使得这个问题,据我环顾四周,从其他人的不同:

而且,我知道,JavaScript的编译我的poco的输出可能会导致未设置的属性根本不可用:

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

但是对于TypeScript强大的打字能力和最近的变化和/或Jest助手,可能还有一些其他选项可以完成这项工作?

回答

1

你的大部分选择都不比那些其他问题的答案更好:初始化属性(好主意);使用属性装饰器(乏味)。

就个人而言,我觉得应该是声明一个类属性作为一个不容待不确定型状string一个错误,然后在构造函数中没有定义它,但feature isn't part of TypeScript的是,即使你打开strictNullChecks (你应该)。我不知道为什么你不想初始化变量,但是这会工作:

export class Foo { 
    public id: number | undefined = void 0; 
    public name: string | undefined = void 0; 
    public when: Date | undefined = void 0; 
} 

现在的Foo一个实例都会有相关的键,如果你做Object.keys()即使值仍然会undefined


等一下,你甚至不使用类在运行时:

const target: Foo = { 
    id: 1001, name: 'whatever', when: new Date() 
}; // object literal, not constructed class instance 
console.log(target instanceof Foo) // false 

那我建议你使用interface代替class,刚打开strictNullChecks

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

const target: Foo = { 
    id: 1001, name: 'whatever', when: new Date() 
}; 
const badTarget: Foo = { 
    id: 1002; 
}; // error, Property 'name' is missing 

现在,TypeScript不会让您为这些属性指定一个可能未定义的值,并且您不必在运行时对任何事情进行循环。

希望有帮助!

相关问题