我有一个TypeScript +2.4项目,我使用Jest进行单元测试。该项目有很多poco模型,没有默认值。例如:
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;
}
问题:有没有办法在我的测试中创建一个帮助器,断言我的TypeScript poco对象的每个属性实际上都赋值了?或者,作为替代方案,Jest是否有一些实用工具?
在SO上有类似的问题,但它们与在测试中断言值无关。这使得这个问题,就我所环顾的而言,与其他问题不同:
另外,我知道我的poco的Javascript编译输出可能会导致未设置的属性根本不可用:
var Foo = (function() {
// nothing here...
}());
但是凭借TypeScript强大的打字能力以及最近的更改和/或Jest助手,可能还有其他一些选项可以完成这项工作?
答案 0 :(得分: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不允许您为这些属性分配可能未定义的值,并且您不必在运行时对任何内容进行循环。
希望有所帮助!