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

165

Qual é a diferença entre expect(something).toBe(true), expect(something).toBeTruthy()e expect(something).toBeTrue()?

Observe que toBeTrue()é um combinador personalizado introduzido jasmine-matchersentre outros combinadores úteis e úteis, como toHaveMethod()ou toBeArrayOfStrings().


A pergunta deve ser genérica, mas, como um exemplo do mundo real, estou testando se um elemento é exibido protractor. Qual fósforo devo usar neste caso?

expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();
alecxe
fonte
3
eu penso .toBe(true)== .toBeTrue(). toBeTruthy () pode ser verdadeiro não apenas sobre true , mas sobre 123 , "dfgdfg", [1,2,3], etc ... basicamente são verdadeiros if(x==true), enquanto if(x===true)são verdadeiros verdadeiros.
dandavis 16/09/2015
2
Isso pode ajudar
ODelibalta
2
Isso dependerá de qual é o valor que você está testando. Use toBeTruthyse você não tiver certeza do tipo, é o mesmo que, == trueenquanto eu suspeito, .toBe(true)é o mesmo que === truevocê mente, é um pouco exagerado chamar uma função para testar se é verdade. Palavra de conselho,. Esquecer ==e !=existir em Javascript e nunca mais usá-lo. A verdade não é necessária e é uma armadilha para iniciantes. Use ===e em !==vez disso.
Blindman67
@ Blindman67 obrigado pelo conselho, faz todo o sentido. Temos até eslintrelatórios se ==ou !=são usados ​​sugerindo alterá-lo para ===e !==.
Alecxe # 23/15

Respostas:

231

O que faço quando me pergunto algo como a pergunta feita aqui é ir à fonte.

ser estar()

expect().toBe() é definido como:

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

Ele realiza seu teste com o ===que significa que, quando usado como expect(foo).toBe(true), passará apenas se foorealmente tiver o valor true. Valores reais não farão o teste passar.

toBeTruthy ()

expect().toBeTruthy() é definido como:

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

Coerção de tipo

Um valor é verdadeiro se a coerção desse valor para um booleano produz o valor true. A operação !!testa a veracidade coagindo o valor passado expectpara um booleano. Observe que, ao contrário do que a resposta atualmente aceita implica , não== true é um teste correto para a veracidade. Você terá coisas engraçadas como

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

Considerando que usando !!rendimentos:

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

(Sim, vazio ou não, uma matriz é verdadeira.)

ser verdadeiro()

expect().toBeTrue()faz parte do Jasmine-Matchers (que é registrado no npm como jasmine-expectapós um projeto posterior registrado jasmine-matchersprimeiro).

expect().toBeTrue() é definido como:

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

A diferença com expect().toBeTrue()e expect().toBe(true)é que expect().toBeTrue()testa se está lidando com um Booleanobjeto. expect(new Boolean(true)).toBe(true)falharia enquanto expect(new Boolean(true)).toBeTrue()passaria. Isso é por causa dessa coisa engraçada:

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

Pelo menos é verdade:

> !!new Boolean(true)
true

Qual é o mais adequado para uso elem.isDisplayed()?

Em última análise, o transferidor entrega esse pedido ao Selenium. A documentação afirma que o valor produzido por .isDisplayed()é uma promessa que resolve para a boolean. Eu aceitaria pelo valor de face e usaria .toBeTrue()ou .toBe(true). Se eu encontrasse um caso em que a implementação retornasse valores verdadeiros / falsos, eu arquivaria um relatório de erro.

Louis
fonte
20

Em javascript, existem verdades e verdades. Quando algo é verdadeiro, é obviamente verdadeiro ou falso. Quando algo é verdade, pode ou não ser um booleano, mas o valor "cast" de é um booleano.

Exemplos.

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

Isso pode simplificar as coisas se você quiser verificar se uma sequência está definida ou se uma matriz possui algum valor.

var users = [];

if(users) {
  // this array is populated. do something with the array
}

var name = "";

if(!name) {
  // you forgot to enter your name!
}

E como indicado. expect(something).toBe(true)e expect(something).toBeTrue()é o mesmo. Mas expect(something).toBeTruthy()não é o mesmo que qualquer um deles.

micah
fonte
2
[] == false;não é correto, a própria afirmação é falsa porque os objetos são sempre truthy
dandavis
@dandavis Good catch
micah
@dandavis Não é verdade. Objetos nem sempre são verdadeiros. Mas essa afirmação [] == false;étrue
micah
2
não, não é útil, exatamente o oposto: é um noob, entendi ... considere [""]==falseou [0]== false; não está vazio, não Falsey, apenas enganosa ...
dandavis
2
Usar o x == trueque você usa em seus exemplos é uma maneira enganosa e, como mostram os comentários acima, de uma maneira incorreta de ilustrar o conceito de veracidade no JavaScript. O verdadeiro teste de veracidade no JavaScript é como um valor se comporta em uma ifdeclaração ou como um operando em uma expressão booleana. Sabemos que 1é verdade porque if (1)fará com que a próxima declaração seja avaliada. Da mesma forma, []é verdade pelo mesmo motivo: Embora seja [] == trueavaliado como false, if ([])ainda fará com que a próxima declaração seja avaliada, portanto sabemos que []é verdade.
Jordan Running
13

Disclamer : Este é apenas um palpite

Eu sei que todo mundo adora uma lista fácil de ler:

  • toBe(<value>) - O valor retornado é o mesmo que <value>
  • toBeTrue() - Verifica se o valor retornado é true
  • toBeTruthy() - Verifique se o valor, quando convertido em um booleano, será um valor verdadeiro

    Truthy valores são todos os valores que não são 0, ''(de cadeia vazio), false, null, NaN, undefinedou [](matriz vazia) *.

    * Observe que, quando você executa !![], ele retorna true, mas quando você executa [] == false, também retorna true. Depende de como é implementado. Em outras palavras:(!![]) === ([] == false)


No seu exemplo, toBe(true)e toBeTrue()produzirá os mesmos resultados.

Ismael Miguel
fonte
Uma matriz vazia é falsey.
Micah
@MicahWilliamson Thanks! Corrigida a resposta
Ismael Miguel
3
matrizes vazias são 100% truthy em JSalert(!![])
dandavis
@dandavis [] == trueno seu console produz false. [] == falseem seu console produztrue
micah
@MicahWilliamson: isso é porque você está comparando a versão de string da matriz (string vazia) com true. pode ser confuso ...
dandavis
1

Existem muitas respostas boas por aí, eu só queria adicionar um cenário em que o uso dessas expectativas possa ser útil. Usando element.all(xxx), se eu precisar verificar se todos os elementos são exibidos em uma única execução, eu posso executar -

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

Razão de ser .all()retorna uma matriz de valores e assim todos os tipos de expectativas ( getText, isPresent, etc ...) pode ser realizada com toBeTruthy()quando .all()entra em cena. Espero que isto ajude.

Girish Sortur
fonte
Agradável! Lembro-me de reduce()colocar a matriz de booleanos em um único valor e depois aplicar a toBe(true)verificação. Isso é muito mais simples, obrigado.
Alecxe