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()
входит в изображение. Надеюсь, это поможет.