开玩笑的 expect.any() 没有按预期工作

Posted

技术标签:

【中文标题】开玩笑的 expect.any() 没有按预期工作【英文标题】:Jest expect.any() not working as expected 【发布时间】:2018-11-13 13:13:53 【问题描述】:

因此,当在基于 Preact(使用 JEST 测试时与 React 没有太大区别)的项目中测试我的一个 reducer 时,我遇到了这个问题:

运行 jest test 时出现以下输出 -

● should setup 

    expect(received).toEqual(expected)

    Expected value to equal:
      "ID": Any<String>, "active": true, "data": Any<Array>
    Received:
      "ID": "BysnEuMlm", "active": true, "data": ["ID": "Hy7wMAz1lm", "code": "dat.fle", "label": "CRES/datum14.cdata", "name": "File", "status": "READY", "value": "format": "cdata", "name": "datum14.cdata", "path": "CRES", "ID": "rkB7RMkeX", "code": "prp.kcv", "label": "3 folds", "name": "k-Fold Cross-Validation", "status": "READY", "value": "3", "ID": "ByCmRfygQ", "code": "ats", "label": undefined, "name": " Best First +  Cfs Subset Eval", "status": "READY", "value": "evaluator": "name": "CfsSubsetEval", "search": "name": "BestFirst", "options": ["-D", "1", "-N", "5"], "use": true, "ID": "HkmVAM1l7", "code": "lrn", "label": undefined, "name": "Naive Bayes", "status": "READY", "value": "label": "Naive Bayes", "name": "bayes.NaiveBayes", "use": true], "output": "format": "pipeline", "name": "jestReact.cpipe", "path": "/home/rupav/opensource/candis/CRES"

    Difference:

    - Expected
    + Received

      Object 
    -   "ID": Any<String>,
    +   "ID": "BysnEuMlm",
        "active": true,
    -   "data": Any<Array>,
    +   "data": Array [
    +     Object 
    +       "ID": "Hy7wMAz1lm",
    +       "code": "dat.fle",
    +       "label": "CRES/datum14.cdata",
    +       "name": "File",
    +       "status": "READY",
    +       "value": Object 
    +         "format": "cdata",
    +         "name": "datum14.cdata",
    +         "path": "CRES",
    +       ,
    +     ,
    +     Object 
    +       "ID": "rkB7RMkeX",
    +       "code": "prp.kcv",
    +       "label": "3 folds",
    +       "name": "k-Fold Cross-Validation",
    +       "status": "READY",
    +       "value": "3",
    +     ,
    +     Object 
    +       "ID": "ByCmRfygQ",
    +       "code": "ats",
    +       "label": undefined,
    +       "name": " Best First +  Cfs Subset Eval",
    +       "status": "READY",
    +       "value": Object 
    +         "evaluator": Object 
    +           "name": "CfsSubsetEval",
    +         ,
    +         "search": Object 
    +           "name": "BestFirst",
    +           "options": Array [
    +             "-D",
    +             "1",
    +             "-N",
    +             "5",
    +           ],
    +         ,
    +         "use": true,
    +       ,
    +     ,
    +     Object 
    +       "ID": "HkmVAM1l7",
    +       "code": "lrn",
    +       "label": undefined,
    +       "name": "Naive Bayes",
    +       "status": "READY",
    +       "value": Object 
    +         "label": "Naive Bayes",
    +         "name": "bayes.NaiveBayes",
    +         "use": true,
    +       ,
    +     ,
    +   ],
    +   "output": Object 
    +     "format": "pipeline",
    +     "name": "jestReact.cpipe",
    +     "path": "/home/rupav/opensource/candis/CRES",
    +   ,
      

以下是测试用例:

test('should setup ', () => 
    const state = documentProcessor(
        undefined,
        
            type: ActionType.Asynchronous.READ_SUCCESS,
            payload: dokuments.active
    )
    // expect(state.active.ID).toEqual(expect.any(String)) - Test case passes iff I run this test with this command only.
    expect(state.active).toEqual(
        data: expect.any(Array),
        active: true,
        ID: expect.any(String),
    )

)

由于调用该 reducer 时状态发生了变化,我需要使用 expect.any 函数,但根据输出,虽然类型相同,但测试没有通过。 而是预期它会出现Any&lt;String&gt;

【问题讨论】:

【参考方案1】:

expect.toEqual 在您的情况下检查 state.active 是否相等。要实现你想要的,你必须做出多个expect 声明:

expect(state.active.active).toEqual(true)
expect(state.active.data).toEqual(expect.any(Array))
expect(state.active.ID).toEqual(expect.any(String))

【讨论】:

感谢您的快速响应,但我真正想要实现的基本上是使用any 仅用于不可避免更改的内容,这里说“ID”。考虑一下,我的 Reducer 返回一个状态,它是一个对象,例如 Z = ID: 'hdgajs35', X:'fixed_data1', Y: 'fixed_data2' 。现在使用您的方法,我只能检查 ID 是否为 String 类型。我永远无法检查状态对象中的 X、Y 以及类似的许多其他字段。我打算这样做:expect(state).toEqual( ID: expect.any(String), ...fixed_state ) 其中 fixed_state 是 Z 但具有不同的 ID。 对不起,我没有明白你的意思。也许您可以更详细地或使用伪代码在测试中添加您想要的内容。无论如何:expect(state).toEqual 很可能不会是你的朋友,因为这匹配对象相等性,只有当你有相同的对象时才会通过。也许 expect(state).toMatchObject 可以帮助你 试过 .toMatchObject,效果很好。但后来,我发现这是我的逻辑错误。现在 .any 在 expect().toEqual() 中工作。 ✨ 非常感谢您的宝贵时间。非常感激。祝它工作成功? 乐于助人。您问题中的代码是否适用于 .toMatchObject 而不是 .toEqual? 是的,.toMatchObject 工作,如文档中所述,toMatchObject 只匹配所有子集,因为我在这个测试用例的逻辑上有错误,我完全比较了错误的对象,现在我不得不转储上面的代码,并使用 expect.any 创建新的测试用例以获得正确的逻辑。【参考方案2】:

你可以使用toMatchObject:

expect(state.active).toMatchObject(
    active: true,
    data: expect.any(Array),
    ID: expect.any(String)
);

更多示例见官方文档:https://jestjs.io/docs/en/expect#tomatchobjectobject

【讨论】:

以上是关于开玩笑的 expect.any() 没有按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 SUM() 字段没有按预期工作?

否定字符没有按预期工作? ^

为啥响应式表没有按预期工作?

为啥我的替换没有按预期工作[重复]

为啥脚手架没有按预期工作?

为啥我的查询没有按预期工作?