toBe(true) vs toBeTruthy() vs toBeTrue()

后端 未结 4 1060
隐瞒了意图╮
隐瞒了意图╮ 2021-01-29 19:12

What is the difference between expect(something).toBe(true), expect(something).toBeTruthy() and expect(something).toBeTrue()?

Note

相关标签:
4条回答
  • 2021-01-29 19:16

    What I do when I wonder something like the question asked here is go to the source.

    toBe()

    expect().toBe() is defined as:

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

    It performs its test with === which means that when used as expect(foo).toBe(true), it will pass only if foo actually has the value true. Truthy values won't make the test pass.

    toBeTruthy()

    expect().toBeTruthy() is defined as:

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

    Type coercion

    A value is truthy if the coercion of this value to a boolean yields the value true. The operation !! tests for truthiness by coercing the value passed to expect to a boolean. Note that contrarily to what the currently accepted answer implies, == true is not a correct test for truthiness. You'll get funny things like

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

    Whereas using !! yields:

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

    (Yes, empty or not, an array is truthy.)

    toBeTrue()

    expect().toBeTrue() is part of Jasmine-Matchers (which is registered on npm as jasmine-expect after a later project registered jasmine-matchers first).

    expect().toBeTrue() is defined as:

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

    The difference with expect().toBeTrue() and expect().toBe(true) is that expect().toBeTrue() tests whether it is dealing with a Boolean object. expect(new Boolean(true)).toBe(true) would fail whereas expect(new Boolean(true)).toBeTrue() would pass. This is because of this funny thing:

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

    At least it is truthy:

    > !!new Boolean(true)
    true
    

    Which is best suited for use with elem.isDisplayed()?

    Ultimately Protractor hands off this request to Selenium. The documentation states that the value produced by .isDisplayed() is a promise that resolves to a boolean. I would take it at face value and use .toBeTrue() or .toBe(true). If I found a case where the implementation returns truthy/falsy values, I would file a bug report.

    0 讨论(0)
  • 2021-01-29 19:19

    In javascript there are trues and truthys. When something is true it is obviously true or false. When something is truthy it may or may not be a boolean, but the "cast" value of is a boolean.

    Examples.

    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
    

    This can make things simpler if you want to check if a string is set or an array has any values.

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

    And as stated. expect(something).toBe(true) and expect(something).toBeTrue() is the same. But expect(something).toBeTruthy() is not the same as either of those.

    0 讨论(0)
  • 2021-01-29 19:22

    There are a lot many good answers out there, i just wanted to add a scenario where the usage of these expectations might be helpful. Using element.all(xxx), if i need to check if all elements are displayed at a single run, i can perform -

    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
    

    Reason being .all() returns an array of values and so all kinds of expectations(getText, isPresent, etc...) can be performed with toBeTruthy() when .all() comes into picture. Hope this helps.

    0 讨论(0)
  • 2021-01-29 19:32

    Disclamer: This is just a wild guess

    I know everybody loves an easy-to-read list:

    • toBe(<value>) - The returned value is the same as <value>
    • toBeTrue() - Checks if the returned value is true
    • toBeTruthy() - Check if the value, when cast to a boolean, will be a truthy value

      Truthy values are all values that aren't 0, '' (empty string), false, null, NaN, undefined or [] (empty array)*.

      * Notice that when you run !![], it returns true, but when you run [] == false it also returns true. It depends on how it is implemented. In other words: (!![]) === ([] == false)


    On your example, toBe(true) and toBeTrue() will yield the same results.

    0 讨论(0)
提交回复
热议问题