Unit testing 类型脚本中的通用测试,该测试断言类上的每个属性都有一个赋值

Unit testing 类型脚本中的通用测试,该测试断言类上的每个属性都有一个赋值,unit-testing,typescript,reflection,jestjs,Unit Testing,Typescript,Reflection,Jestjs,我有一个TypeScript+2.4项目,我在其中使用Jest进行单元测试。该项目有很多poco模型,没有默认值。例如: export class Foo { public id: number public name: string; public when: Date; } 每个模型都从原始json映射到此类。我的测试要求分配所有属性,例如具有值。这导致必须为所有型号编写以下测试: test('Foo() should have its properties ass

我有一个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仅迭代已分配的属性,而忽略未设置的属性(因此始终为正值):

示例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是否有一些用于此的util

在这方面也有类似的问题,但它们与在测试中断言值无关。就我所看到的而言,这使得这个问题与其他问题有所不同:

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

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

但是,有了TypeScript强大的打字能力和最近的更改和/或Jest助手,可能还有一些额外的选项来完成这项工作

您的大多数选项并不比其他问题的答案更好:初始化属性(好主意);使用属性装饰器(单调乏味)

就个人而言,我认为将类属性声明为像
string
这样的不能未定义的类型,然后不在构造函数中定义它应该是一个错误,但即使您启用了
stricnullchecks
(您应该这样做)。我不知道您为什么不想初始化变量,但这样可以:

export class Foo {
    public id: number | undefined = void 0;
    public name: string | undefined = void 0;
    public when: Date | undefined = void 0;
}
现在,如果执行
Object.keys()
,则
Foo
的实例将具有相关的键,即使值仍然是
未定义的


等等,您甚至没有在运行时使用该类:

const target: Foo = { 
    id: 1001, name: 'whatever', when: new Date()
}; // object literal, not constructed class instance
console.log(target instanceof Foo) // false
然后我建议您使用
接口
而不是
,只需打开
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将不允许您为这些属性分配可能未定义的值,并且您不必在运行时费心循环任何内容

希望有帮助

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