是否可以在name
的{{1}}部分内访问对象的密钥?
.each
答案 0 :(得分:2)
Jest describe.each期望第一个参数中包含数组。如果您传入一维数组,则在内部会将其映射到数组数组(即,传递[1, 2, 3]
作为第一个参数将转换为[[1], [2], [3]]
)。
该数组内部的每个数组均用作测试套件的数据。因此,在上一个示例中,describe.each
将生成三个测试套件,第一个以1
作为数据,第二个以2
作为数据,第三个以3
作为数据
现在,在测试套件名称中,您只能格式化要提供给它的参数。就您而言,您要将accounts
数组的每个对象中的数据传递给每个测试套件。因此,当您在测试套件名称中设置格式说明符时,它们将应用于整个帐户对象(即示例中的%s
将使您的对象字符串化,从而产生[object Object]
)。不幸的是,我认为您不能将格式说明符应用于对象的键。
一些想法可以实现您想要的:
如果使用%s
格式化程序编写测试套件名称,则将调用Object的toString
方法(默认情况下返回[object Object]
)。
如果您在每个帐户对象中定义一个toString
方法,则将使用该方法。因此,我们可以使用以下代码将toString
方法添加到每个帐户对象中(请注意,我们添加的toString
方法将返回type
键的值): / p>
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; } }));
现在,使用%s
格式说明符,您应该在每个测试套件中看到帐户类型:
describe.each(accounts)(
"%s", // <-- This will cause the toString method to be called.
function (account)
{
// test code
}
)
您始终可以重新定义每个测试套件数据,以便第一个参数是帐户类型(请注意,现在accounts
是2D数组):
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"
},
]
]
您现在可以使用第一个参数(即帐户类型)为测试套件命名:
describe.each(accounts)(
'%s', // <-- This %s will format the first item in each test suite array.
function (accountType, account) {
// test code
}
);
请注意,由于每个测试套件数组都有两个元素,因此您的测试函数现在接收两个参数。第一个是帐户类型,第二个是帐户数据。
您可以使用标记的模板文字形式describe.each。使用此解决方案,您不必更改accounts
数组的当前定义。
describe.each`
account
${accounts[0]}
${accounts[1]}
`('$account.type', function (account) {
// test code
});
该解决方案的缺点是,您必须在模板文字中手动将每个测试套件数据添加到新行中(即,如果将新元素添加到accounts
数组中,则必须记住要添加它在模板文字中以${accounts[2]}
换行)。
答案 1 :(得分:1)
您可以映射初始帐户数组,以将每个帐户转换为包含2个项目的数组:
现在,您可以使用describe
名称中的第一个元素数组
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();
});
},
);
答案 2 :(得分:0)
我在对象上也遇到类似的问题。我想根据http错误代码测试错误消息,因此我编写了一个测试对象,如下所示:
const expectedElements = {
error: {
code: 500,
title: "Problème avec l'API"
},
notFound:{
code: 404,
title: "Élement absent"
},
unauthorized:{
code: 401,
title: "Accès non autorisé"
}
};
我用Object.entries(obj)
得到了一个数组,其中的条目是这样写的:['key','value']
。我可以在测试中将它们作为两个参数来访问。这是我的写法:
test.each(Object.entries(expectedElements))("NoAccess show the right element for %s",(key,expectedElement)=>{
const { getByRole } = render(<NoAccess apiStatusCode={expectedElement.code}/>);
//test code
});
现在,我可以根据需要添加任意多个案例,而不必重写测试或创建数组。我只是在expectedElements
对象中写一个新值。另外,我还有一个描述性的测试名称!