toBe (true) против toBeTruthy () против toBeTrue ()

167

В чем разница 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();
alecxe
источник
3
я думаю .toBe(true)== .toBeTrue(). toBeTruthy () может быть истинным не только по истине , но по 123 , "dfgdfg", [1,2,3] и т. д ... в основном if(x==true)верны, в то время if(x===true)как верны истины.
Дандавис
2
Это будет зависеть от того, какое значение вы тестируете. Используйте, toBeTruthyесли вы не уверены в типе, он такой же, как в == trueто время, как я подозреваю .toBe(true), тот же, что и === trueMind you, немного за борт, чтобы вызвать функцию для проверки на true. Слово совета. Забудьте ==и !=существует в Javascript и никогда не используйте его снова. Правда не нужна и ловушка для начинающих. Используйте ===и !==вместо.
Blindman67
@ Blindman67 спасибо за совет, в этом есть смысл. Мы даже eslintсообщаем нам, если ==или !=используем, предлагая изменить его на ===и !==.
Алекса

Ответы:

232

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

быть()

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логическому значению . Обратите внимание, что вопреки тому, что подразумевает принятый в настоящее время ответ , == 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 (которая зарегистрирована на 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). Если бы я нашел случай, когда реализация возвращает значения «истина / ложь», я бы отправил отчет об ошибке.

Луис
источник
21

В 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()это не одно и то же.

Михей
источник
2
[] == false;неверно, само утверждение неверно, потому что объекты всегда правдивы
dandavis
@dandavis Хороший улов
Михей
@dandavis Не правда. Объекты не всегда правдивы. Но это утверждение [] == false;являетсяtrue
Миха
2
нет, это бесполезно, как раз наоборот: это нуб-ха-ха ... подумай [""]==falseили [0]== false; не пустой, не фальшивый, просто обманчивый ...
Дандавис
2
Использование, x == trueкак вы используете в своих примерах, вводит в заблуждение и, как показывают приведенные выше комментарии, неверный способ проиллюстрировать концепцию правдивости в JavaScript. Настоящий тест на достоверность в JavaScript - это то, как значение ведет себя в ifвыражении или как операнд в логическом выражении. Мы знаем, что 1это правда, потому что if (1)это приведет к оценке следующего утверждения. Точно так []же правдива по той же причине: даже если она будет [] == trueоценена false, if ([])она все равно вызовет оценку следующего утверждения, поэтому мы знаем, что []это правда.
Джордан, бегущий
14

Disclamer : это просто дикая догадка

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

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

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

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


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

Исмаэль Мигель
источник
Пустой массив - фальси.
Май
@MicahWilliamson Спасибо! Исправлен ответ
Исмаэль Мигель
3
пустые массивы на 100% правдивы в JSalert(!![])
dandavis
@dandavis [] == trueв вашей консоли производит false. [] == falseу тебя консоль выдаетtrue
миха
@MicahWilliamson: это потому, что вы сравниваете строковую версию массива (пустую строку) с истинной. это может сбивать с толку ...
Дандавис
1

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

Гириш Сортур
источник
Ницца! Я помню, reduce()что - массив логических значений в одном значении и затем применение toBe(true)проверки. Это намного проще, спасибо.
Алексей