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

后端 未结 4 1067
隐瞒了意图╮
隐瞒了意图╮ 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.

提交回复
热议问题