jest .each 名称访问对象键

A. *_*Lau 14 javascript arrays object ecmascript-6 jestjs

是否可以在 a 的name部分内访问对象的键.each

let accounts =
    [
        {
            details:
            {
                company_name:
                    "company_name",
                email,
                password:
                    "asdf",
            },
            find:
            [
                "_id",
                "company_name",
                "email",
                "type",
            ],
            type:
                "creator"
        },
        {
            details:
            {
                email,
                first_name:
                    "first_name",
                last_name:
                    "last_name",
                password:
                    "asdf",
            },
            find:
            [
                "_id",
                "email",
                "first_name",
                "last_name",
                "type",
            ],
            type:
                "user"
        },
    ]

describe.each(accounts)(
    "%s", // <-- access the 'type' key, e.g. account.type
    function (account)
    {
        // test code
    }
)
Run Code Online (Sandbox Code Playgroud)

ast*_*tef 29

正如现代医生所说,你可以

通过使用 $variable 注入测试用例对象的属性来生成唯一的测试标题

简单地说:

describe.each(accounts)(
    "$type",
    function (account) {
        // tests
    }
)
Run Code Online (Sandbox Code Playgroud)

您可以像这样访问嵌套对象值:$variable.path.to.value

在水平上也是如此test.each

  • 确保您为此安装了正确的版本。此功能仅支持“27.0+” (14认同)

mga*_*cia 19

Jest describe.each在第一个参数需要一个数组数组。如果你传入一个一维数组,它在内部将被映射到一个数组数组(即[1, 2, 3]作为第一个参数传递将被转换为[[1], [2], [3]])。

数组内的每个数组都用作测试套件的数据。因此,在前面的示例中,describe.each将生成三个测试套件,第一个带有1as 数据,第二个带有2as 数据,第三个带有3as 数据。

现在,在测试套件名称中,您只能格式化您提供给它的参数。在您的情况下,您将accounts数组的每个对象中的数据传递给每个测试套件。因此,当您在测试套件名称中设置格式说明符时,它们将应用于整个帐户对象(即%s在您的示例中将字符串化您的对象,结果为[object Object])。不幸的是,我认为您不能将格式说明符应用于对象的键。

一些想法来完成你想要的:

解决方案1

如果您使用%s格式化程序来编写测试套件名称,toString则将调用 Object的方法(默认情况下返回[object Object])。

如果您toString在每个帐户对象中定义一个方法,则将使用该方法。因此,我们可以toString使用以下代码将方法添加到每个帐户对象中(请注意,toString我们添加的方法是返回type键的值):

const accounts = [{
    details: {
        company_name: "company_name",
        email: "aa",
        password: "asdf",
    },
    find: [ "_id", "company_name", "email", "type", ],
    type: "creator"
}, {
    details: {
        email: 'bb',
        first_name: "first_name",
        last_name: "last_name",
        password: "asdf",
    },
    find: [ "_id", "email", "first_name", "last_name", "type", ],
    type: "user"
}].map(account => Object.assign(account, { toString: function() { return this.type; } }));
Run Code Online (Sandbox Code Playgroud)

现在,使用%s格式说明符,您应该可以在每个测试套件中看到帐户类型:

describe.each(accounts)(
    "%s", // <-- This will cause the toString method to be called.
    function (account)
    {
        // test code
    }
)
Run Code Online (Sandbox Code Playgroud)

解决方案2

您始终可以重新定义每个测试套件数据,以便第一个参数是帐户类型(请注意,现在accounts是一个二维数组):

let accounts = [
    [
        "creator",
        {
            details: {
                company_name: "company_name",
                email: "email",
                password: "asdf",
            },
            find: [ "_id", "company_name", "email", "type", ],
            type: "creator"
        }
    ], [
        "user", 
        {
            details: {
                email: "email",
                first_name: "first_name",
                last_name: "last_name",
                password: "asdf",
            },
            find: [ "_id", "email", "first_name", "last_name", "type", ],
            type: "user"
        },
    ]
]
Run Code Online (Sandbox Code Playgroud)

您现在可以使用第一个参数(即帐户类型)为测试套件命名:

describe.each(accounts)(
    '%s',  // <-- This %s will format the first item in each test suite array.
    function (accountType, account) {
        // test code
    }
); 
Run Code Online (Sandbox Code Playgroud)

请注意,现在您的测试函数接收两个参数,因为每个测试套件数组都有两个元素。第一个是账户类型,第二个是账户数据。

解决方案3

您可以使用describe.each的标记模板文字形式。使用此解决方案,您无需更改当前的accounts数组定义。

describe.each`
    account
    ${accounts[0]}
    ${accounts[1]}
`('$account.type', function (account) { 
    // test code
});
Run Code Online (Sandbox Code Playgroud)

此解决方案的缺点是您必须在新行中手动附加模板文字中的每个测试套件数据(即,如果您将新元素添加到accounts数组中,您必须记住将其添加到模板文字中的新行中作为${accounts[2]})。


Ser*_*eni 12

您可以映射初始帐户数组以将每个帐户转换为包含 2 个项目的数组:

  1. 账户类型
  2. 初始帐户元素

现在,您可以使用describename 中的第一个元素数组

describe.each(accounts.map(account => [account.type, account]))(
    'testing %s', // %s replaced by account type
    (type, account) => { // note: 2 arguments now
        it('details should be defined ', () => {
            expect(account.details).toBeDefined();
        });
    },
);

Run Code Online (Sandbox Code Playgroud)


Ale*_*ard 5

我对一个对象也有类似的问题。我想根据http错误代码测试错误消息,所以我编写了一个测试对象,如下所示:

\n
const expectedElements = {\n  error: {\n    code: 500,\n    title: "Probl\xc3\xa8me avec l\'API"\n  },\n  notFound:{\n    code: 404,\n    title: "\xc3\x89lement absent"\n  },\n  unauthorized:{\n    code: 401,\n    title: "Acc\xc3\xa8s non autoris\xc3\xa9"\n  }\n};\n\n
Run Code Online (Sandbox Code Playgroud)\n

我曾经Object.entries(obj)得到一个数组,其中的条目如下所示:[\'key\',\'value\']。我可以在测试中将它们作为两个参数进行访问。我是这样写的:

\n
test.each(Object.entries(expectedElements))("NoAccess show the right element for %s",(key,expectedElement)=>{\n    const { getByRole } = render(<NoAccess apiStatusCode={expectedElement.code}/>);\n    //test code\n  });\n\n
Run Code Online (Sandbox Code Playgroud)\n

现在我可以根据需要添加案例,而不必重写测试或创建数组。我只是在我的对象中写入一个新值expectedElements。另外,我还有一个描述性的测试名称!

\n