【问题标题】:toBe(true) vs toBeTruthy() vs toBeTrue()toBe(true) vs toBeTruthy() vs toBeTrue()
【发布时间】:2015-12-13 11:02:24
【问题描述】:

expect(something).toBe(true)expect(something).toBeTruthy()expect(something).toBeTrue() 有什么区别?

请注意,toBeTrue() 是在jasmine-matchers 中引入的自定义匹配器,以及其他有用且方便的匹配器,例如toHaveMethod()toBeArrayOfStrings()


这个问题是通用的,但是,作为一个真实的例子,我正在测试一个元素是否显示在protractor 中。在这种情况下我应该使用哪个匹配器?

expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();

【问题讨论】:

  • 我认为.toBe(true)==.toBeTrue()。 toBeTruthy() 不仅在 true 时为真,而且在 123、“dfgdfg”、[1,2,3] 等时为真……基本上if(x==true) 是真实,而if(x===true) 是真实的。
  • 这将取决于您要测试的值是什么。如果您不确定类型与== true 相同,请使用toBeTruthy,而我怀疑.toBe(true)=== true 相同请注意,调用函数来测试是否为真有点过分。忠告,。忘记 Javascript 中存在的 ==!=,永远不要再使用它。不需要真实,并且是初学者的陷阱。请改用===!==
  • @Blindman67 感谢您的建议,这很有意义。如果使用了==!=,我们甚至有eslint 报告我们,建议将其更改为===!==

标签: javascript testing jasmine protractor jasmine-matchers


【解决方案1】:

当我想知道类似这里提出的问题时,我会做的是去源头。

toBe()

expect().toBe() 定义为:

function toBe() {
  return {
    compare: function(actual, expected) {
      return {
        pass: actual === expected
      };
    }
  };
}

它使用=== 执行测试,这意味着当用作expect(foo).toBe(true) 时,只有当foo 实际上具有值true 时才会通过。真实值不会使测试通过。

toBeTruthy()

expect().toBeTruthy() 定义为:

function toBeTruthy() {
  return {
    compare: function(actual) {
      return {
        pass: !!actual
      };
    }
  };
}

类型强制

如果将该值强制转换为布尔值产生值true,则该值是真值。操作!! 通过将传递给expect 的值强制为布尔值来测试真实性。请注意,与当前接受的答案 implies 不同,== true 不是正确的真实性测试。你会得到一些有趣的东西,比如

> "hello" == true
false
> "" == true
false
> [] == true
false
> [1, 2, 3] == true
false

而使用!! 会产生:

> !!"hello"
true
> !!""
false
> !![1, 2, 3]
true
> !![] 
true

(是的,无论是否为空,数组都是真实的。)

toBeTrue()

expect().toBeTrue()Jasmine-Matchers 的一部分(在后来的项目首先注册jasmine-matchers 之后,它在npm 上注册为jasmine-expect)。

expect().toBeTrue() 定义为:

function toBeTrue(actual) {
  return actual === true ||
    is(actual, 'Boolean') &&
    actual.valueOf();
}

expect().toBeTrue()expect().toBe(true) 的区别在于expect().toBeTrue() 测试它是否在处理Boolean 对象。 expect(new Boolean(true)).toBe(true) 会失败,而 expect(new Boolean(true)).toBeTrue() 会通过。这是因为这个有趣的事情:

> new Boolean(true) === true
false
> new Boolean(true) === false
false

至少它是真实的:

> !!new Boolean(true)
true

哪个最适合与elem.isDisplayed()一起使用?

最终 Protractor 将此请求交给 Selenium。 documentation 声明.isDisplayed() 产生的值是一个可以解析为boolean 的承诺。我会从表面上看它并使用.toBeTrue().toBe(true)。如果我发现实现返回真值/假值的情况,我会提交错误报告。

【讨论】:

    【解决方案2】:

    免责声明:这只是一个疯狂的猜测

    我知道每个人都喜欢易于阅读的列表:

    • toBe(<value>) - 返回值与<value> 相同
    • toBeTrue() - 检查返回值是否为 true
    • toBeTruthy() - 检查该值在转换为布尔值时是否为真值

      真实值是不是0''(空字符串)、falsenullNaNundefined[](空数组)的所有值*。

      * 请注意,当您运行!![] 时,它会返回true,但是当您运行[] == false 时,它也会返回true。这取决于它是如何实现的。换句话说:(!![]) === ([] == false)


    在您的示例中,toBe(true)toBeTrue() 将产生相同的结果。

    【讨论】:

    • 空数组是假的。
    • @MicahWilliamson 谢谢!修复了答案
    • 空数组在 JS 中是 100% 真实的 alert(!![])
    • @dandavis [] == true 在您的控制台中生成 false[] == false 在你的控制台中产生 true
    • 你的comment asked 为什么你被否决了。认为您可能仍然会欣赏一个解释(不要发布“疯狂的猜测”)。无论如何,在这一点上,请记住,对于未来的读者来说,答案可能比原来的提问者更多,所以将你的答案从“只是一个疯狂的猜测”改进为明确的答案永远不会太晚。
    【解决方案3】:

    在javascript中有trues和truthys。当某事为真时,它显然是真或假。当某事为真时,它可能是布尔值,也可能不是布尔值,但 的“转换”值是布尔值。

    示例。

    true == true; // (true) true
    1 == true; // (true) truthy
    "hello" == true;  // (true) truthy
    [1, 2, 3] == true; // (true) truthy
    [] == false; // (true) truthy
    false == false; // (true) true
    0 == false; // (true) truthy
    "" == false; // (true) truthy
    undefined == false; // (true) truthy
    null == false; // (true) truthy
    

    如果您想检查是否设置了字符串或数组是否有任何值,这可以使事情变得更简单。

    var users = [];
    
    if(users) {
      // this array is populated. do something with the array
    }
    
    var name = "";
    
    if(!name) {
      // you forgot to enter your name!
    }
    

    如前所述。 expect(something).toBe(true)expect(something).toBeTrue() 是一样的。但是expect(something).toBeTruthy() 和这两个都不一样。

    【讨论】:

    • [] == false; 不正确,陈述本身是错误的,因为对象总是真实的
    • @dandavis 不正确。对象并不总是真实的。但是那个声明[] == false;true
    • 好的,你明白了,让我纠正自己。除了 null 之外的内置对象总是真实的...... [] 虽然是真实的。
    • 不,它没有用,事实上恰恰相反:这是一个菜鸟陷阱......考虑[""]==false[0]== false;不是空的,不是虚的,只是骗人的……
    • 在您的示例中使用x == true 是一种误导,并且如上面的 cmets 所示,在 JavaScript 中说明真实性概念的方式不正确。 JavaScript 中真实性的真正测试是值在if 语句中的行为方式或作为布尔表达式中的操作数的行为方式。我们知道1 是真实的,因为if (1) 将导致对下一条语句进行评估。同样,[] 为真,原因相同:即使[] == true 的计算结果为falseif ([]) 仍会导致对下一条语句进行求值,因此我们知道[] 为真。
    【解决方案4】:

    当您阅读下面的示例时,请记住这一区别

    true === true // true
    "string" === true // false
    1 === true // false
    {} === true // false
    

    但是

    Boolean("string") === true // true
    Boolean(1) === true // true
    Boolean({}) === true // true
    

    1。期望(语句).toBe(真)

    当传递给expect() 的语句计算为true 时,断言通过

    expect(true).toBe(true) // pass
    expect("123" === "123").toBe(true) // pass
    

    在所有其他情况下,它都会失败

    expect("string").toBe(true) // fail
    expect(1).toBe(true); // fail
    expect({}).toBe(true) // fail
    

    即使在执行Boolean() 时,所有这些语句都会评估为true

    所以你可以把它看作是“严格”的比较

    2。期望(语句).toBeTrue()

    这与.toBe(true) 的比较类型完全相同,但最近在Jasmine 中的3.5.0 版本于2019 年9 月20 日引入

    3。期望(语句).toBeTruthy()

    另一方面,toBeTruthy 将语句的输出评估为布尔值,然后进行比较

    expect(false).toBeTruthy() // fail
    expect(null).toBeTruthy() // fail
    expect(undefined).toBeTruthy() // fail
    expect(NaN).toBeTruthy() // fail
    expect("").toBeTruthy() // fail
    expect(0).toBeTruthy() // fail
    

    例如,在所有其他情况下,它都会通过

    expect("string").toBeTruthy() // pass
    expect(1).toBeTruthy() // pass
    expect({}).toBeTruthy() // pass
    

    【讨论】:

      【解决方案5】:

      那里有很多很好的答案,我只是想添加一个场景,使用这些期望可能会有所帮助。使用element.all(xxx),如果我需要检查所有元素是否在一次运行中显示,我可以执行 -

      expect(element.all(xxx).isDisplayed()).toBeTruthy(); //Expectation passes
      expect(element.all(xxx).isDisplayed()).toBe(true); //Expectation fails
      expect(element.all(xxx).isDisplayed()).toBeTrue(); //Expectation fails
      

      .all() 的原因返回一个值数组,因此当出现.all() 时,可以使用toBeTruthy() 执行各种期望(getTextisPresent 等...)。希望这会有所帮助。

      【讨论】:

      • 不错!我记得reduce()-将布尔数组转换为单个值,然后应用toBe(true) 检查。这要简单得多,谢谢。
      猜你喜欢
      • 2014-04-20
      • 1970-01-01
      • 2013-12-23
      • 2012-03-23
      • 2017-01-23
      • 1970-01-01
      • 2015-02-12
      相关资源
      最近更新 更多