ToBe (true) vs toBeTruthy() vs toBeTrue()

В чем разница между 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();

Ответ 1

Что я делаю, когда мне интересно, что-то вроде вопроса, заданного здесь, идет к источнику.

Тоба()

expect().toBe() определяется как:

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

Он выполняет свой тест с ===, что означает, что при использовании в качестве expect(foo).toBe(true) он будет проходить, только если foo имеет значение true. Значения Truthy не будут проходить тест.

toBeTruthy()

expect().toBeTruthy() определяется как:

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

Тип принуждения

Значение является правдивым, если принуждение этого значения к булеву дает значение true. Операция !! проверяет правдоподобие, вызывая значение, переданное в expect, на логическое значение. Обратите внимание, что в противоположность тому, что подразумевается в текущем принятом ответе , == true является not правильным критерием правдоподобия. Вы получите такие забавные вещи, как

> "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 (который зарегистрирован на npm как jasmine-expect после того, как был зарегистрирован более поздний проект jasmine-matchers).

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()?

В конечном счете Транспортир передает эту просьбу Селену. В документации указано, что значение, созданное .isDisplayed(), является обещанием, которое разрешает Boolean. Я бы взял его по номиналу и использовал .toBeTrue() или .toBe(true). Если бы я нашел случай, когда реализация возвращает значения правды/фальшивки, я бы сделал отчет об ошибке.

Ответ 2

В javascript есть истины и правды. Когда что-то истинно, это, очевидно, верно или ложно. Когда что-то правдиво, оно может быть или не быть логическим, но значение "cast" является логическим.

Примеры.

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() не то же самое, что любой из них.

Ответ 3

Disclamer. Это просто дикое предположение

Я знаю, что все любят легко читаемый список:

  • toBe(<value>) - Возвращаемое значение совпадает с <value>
  • toBeTrue() - проверяет, является ли возвращаемое значение true
  • toBeTruthy() - Проверьте, будет ли значение при приведении в булево значение правды

    Truthy - это все значения, которые не являются 0, '' (пустая строка), false, null, NaN, undefined или [] (пустой массив) *.

    * Обратите внимание, что при запуске !![] он возвращает true, но при запуске [] == false он также возвращает true. Это зависит от того, как оно реализовано. Другими словами: (!![]) === ([] == false)


В вашем примере toBe(true) и toBeTrue() будут давать те же результаты.

Ответ 4

Есть много хороших ответов, я просто хотел добавить сценарий, в котором использование этих ожиданий может оказаться полезным. Используя 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() возвращает массив значений, и поэтому все виды ожиданий (getText, isPresent и т.д.) могут быть выполнены с помощью toBeTruthy(), когда .all() входит в изображение. Надеюсь, это поможет.