玩笑.each名称访问对象键

时间:2019-06-28 01:49:54

标签: javascript arrays object ecmascript-6 jestjs

是否可以在name的{​​{1}}部分内访问对象的密钥?

.each

3 个答案:

答案 0 :(得分:2)

Jest describe.each期望第一个参数中包含数组。如果您传入一维数组,则在内部会将其映射到数组数组(即,传递[1, 2, 3]作为第一个参数将转换为[[1], [2], [3]])。

该数组内部的每个数组均用作测试套件的数据。因此,在上一个示例中,describe.each将生成三个测试套件,第一个以1作为数据,第二个以2作为数据,第三个以3作为数据

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

一些想法可以实现您想要的:

解决方案1 ​​

如果使用%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
    }
)

解决方案2

您始终可以重新定义每个测试套件数据,以便第一个参数是帐户类型(请注意,现在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
    }
); 

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

解决方案3

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

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

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

答案 1 :(得分:1)

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

  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对象中写一个新值。另外,我还有一个描述性的测试名称!