O que é "afirmar" em JavaScript?

263

O que assertsignifica JavaScript?

Eu já vi algo como:

assert(function1() && function2() && function3(), "some text");

E gostaria de saber o que o método assert()faz.

frrlod
fonte

Respostas:

367

Não existe assertno JavaScript (ainda; fala-se em adicionar um , mas está em um estágio inicial). Talvez você esteja usando alguma biblioteca que fornece uma. O significado usual é gerar um erro se a expressão passada para a função for falsa; isso faz parte do conceito geral de verificação de asserção . Normalmente, as asserções (como são chamadas) são usadas apenas nas compilações "testing" ou "debug" e são removidas do código de produção.

Suponha que você tivesse uma função que deveria sempre aceitar uma string. Você gostaria de saber se alguém chamou essa função com algo que não era uma string. Então você pode fazer:

assert(typeof argumentName === "string");

... onde assertgeraria um erro se a condição fosse falsa.

Uma versão muito simples seria assim:

function assert(condition, message) {
    if (!condition) {
        throw message || "Assertion failed";
    }
}

Melhor ainda, use o Errorobjeto se o mecanismo JavaScript o suportar (os realmente antigos podem não), que tem a vantagem de coletar um rastreamento de pilha e assim:

function assert(condition, message) {
    if (!condition) {
        message = message || "Assertion failed";
        if (typeof Error !== "undefined") {
            throw new Error(message);
        }
        throw message; // Fallback
    }
}

Até o IE8 possui Error(embora não possua a stackpropriedade, mas os mecanismos modernos [incluindo o IE moderno] possuem ).

TJ Crowder
fonte
6
... ficando empolgado com tipos em JS? Eu diria que essa é uma das piores razões para isso assert.
cHao 9/03/13
137
@cHao: Existem casos de uso válidos. Foi apenas o primeiro exemplo que veio à mente. O exemplo não é o ponto. O conceito de afirmações é o ponto.
TJ Crowder
4
algo que eu adicionei ao meu código dentro da if(!condition)configuração está em var throwError=true;seguida debugger;, envolva a seção throw em um if(throwError). Dessa forma, se o depurador estiver aberto, ele quebrará e, se desejar, posso definir throwErrorfalse e examinar todos os escopos ao sair.
Rick
8
@Rick, se você usa o Chrome DevTools, pode simplesmente ativar "Pausar em exceções não capturadas" na guia Fontes e ele será interrompido automaticamente no throw. Dessa forma, você não precisa da debugger;declaração. Veja developer.chrome.com/devtools/docs/… para mais.
Vicky Chijwani
1
@machineghost: não vejo como isso é "mais simples", você acabou de trocar ifpor um operador condicional. De qualquer forma, no mundo de hoje, eu não me incomodaria em oferecer suporte a motores que não possuem Error.
TJ Crowder #
157

Se você estiver usando um navegador moderno ou nodejs, poderá usar console.assert(expression, object).

Para maiores informações:

joaoprib
fonte
46
Para sua informação, isso funciona mais como console.erroro código continua sendo executado.
Daniel Sokolowski
10
@DanielSokolowski, Exatamente. console.assertnão é tão bom, a menos que tenha o mesmo comportamento de throw.
Pacerier 23/05
23
A razão pela qual a execução continua depois console.asserté porque as asserções não são funções de manipulação de erros. Eles são projetados para verificação de correção de código apenas durante o desenvolvimento. Tradicionalmente, eles são completamente desativados em ambientes de produção para evitar que os sistemas ativos sejam encerrados devido a algo trivial. O navegador é considerado um ambiente de produção, portanto console.assert, não encerra a execução no local. Se você está confiando em asserções para interromper a execução, deve usar o tratamento de erros adequado, pois não é para isso que as asserções são destinadas.
Malvineous 10/09/16
8
@ RonBurk: Os designers de idiomas decidiram "para que servem as afirmações". No C ++, [uma asserção] foi projetada para capturar erros de programação, não erros de usuário ou de tempo de execução, pois geralmente é desativada depois que um programa sai da fase de depuração. O PHP diz que, como regra geral, seu código sempre poderá funcionar corretamente se a verificação de asserções não estiver ativada. A voz passiva não pretendia dar autoridade a uma preferência pessoal, mas sim relatar o que é prática geral amplamente aceita.
Malvineous 7/03/17
4
@ Don: Ponto tomado, mas eu estava apenas citando as páginas vinculadas. Acredito que as asserções devem ser tratadas como se pudessem ser desabilitadas, apenas porque seu código pode um dia ser usado por alguém que acha que é seguro fazê-lo. Se as asserções forem críticas para o seu código, acho que elas realmente devem ser atualizadas para a verificação de erros adequada, em vez de depender de um método de depuração que nem sempre garante a finalização da execução. Sem mencionar que ter seu código repetidamente morto em um ambiente de produção, quando ele poderia retornar um erro e continuar, poderia causar mais estresse do que vale a pena!
Malvineous
29

As outras respostas são boas: não há uma função assert embutida no ECMAScript5 (por exemplo, JavaScript que funciona basicamente em todos os lugares), mas alguns navegadores fornecem a você ou têm complementos que fornecem essa funcionalidade. Embora seja provavelmente melhor usar uma biblioteca bem estabelecida / popular / mantida para isso, para fins acadêmicos, uma função de "afirmação do pobre" pode ser algo como isto:

const assert = function(condition, message) {
    if (!condition)
        throw Error('Assert failed: ' + (message || ''));
};

assert(1 === 1); // Executes without problem
assert(false, 'Expected true');
// Yields 'Error: Assert failed: Expected true' in console
iX3
fonte
BTW, pode-se modificar isso facilmente, de forma a gerar apenas um erro em ambientes de desenvolvimento (por exemplo, envolvendo outro se / adicionando outro condicional) e, caso contrário, não faz nada ou apenas imprime um aviso. Pessoalmente, minha opinião é que as asserções devem estar apenas no código de teste (por exemplo, verificar se os resultados esperados e reais correspondem); no código de produção, devem ser quer supérfluo (garantida correcta por desenho) e, assim, removido ou apenas para guardar utilizador de entrada / externo, caso em que pode ser substituído por desinfecção lógica e manuseio excepção padrão (por exemplo try, catch, throw)
IX3
8

assert()não é uma função javascript nativa. É uma função personalizada que alguém criou. Você precisará procurá-lo em sua página ou em seus arquivos e publicá-lo para qualquer pessoa para ajudar a determinar o que está fazendo.

Crayon Violent
fonte
5

verifique isto: http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-quick-and-easy-javascript-testing-with-assert/

é para testar JavaScript. Surpreendentemente, em apenas cinco ou seis linhas, esse código fornece um grande nível de poder e controle sobre seu código durante o teste.

A função assert aceita dois parâmetros:

resultado: um booleano, que indica se o teste foi aprovado ou reprovado

description: uma breve descrição do seu teste.

A função assert simplesmente cria um item da lista, aplica uma classe de "aprovação" ou "falha", dependendo se seu teste retornou verdadeiro ou falso, e depois anexa a descrição ao item da lista. Finalmente, esse bloco de código é adicionado à página. É uma loucura simples, mas funciona perfeitamente.

Amrendra
fonte
4

Aqui está uma implementação realmente simples de uma função assert. É preciso um valor e uma descrição do que você está testando.

 function assert(value, description) {
        var result = value ? "pass" : "fail";
        console.log(result + ' - ' +  description); 
    };

Se o valor for avaliado como verdadeiro, ele passa.

assert (1===1, 'testing if 1=1');  

Se retornar falso, falhará.

assert (1===2, 'testing if 1=1');
joshpierro
fonte
1
O objetivo de uma asserção não é registrar no stdout no nível de informações, mas interromper a execução do programa (geralmente gerando uma exceção) e registrar no stderr se a asserção for avaliada como falsa.
Nuno André
4

Se a asserção for falsa, a mensagem será exibida. Especificamente, se o primeiro argumento for falso, o segundo argumento (a mensagem da sequência) será registrado no console das ferramentas do desenvolvedor. Se o primeiro argumento for verdadeiro, basicamente nada acontece. Um exemplo simples: estou usando as Ferramentas do desenvolvedor do Google:

var isTrue = true;
var isFalse = false;
console.assert(isTrue, 'Equals true so will NOT log to the console.');
console.assert(isFalse, 'Equals false so WILL log to the console.');
Gato maluco
fonte
3

Provavelmente veio com uma biblioteca de testes que parte do seu código está usando. Aqui está um exemplo de um (é provável que não seja a mesma biblioteca que seu código está usando, mas mostra a ideia geral):

http://chaijs.com/guide/styles/#assert

Matt Browne
fonte
2

A palavra ou função "afirmar" é usada principalmente no teste de partes do aplicativo.

As funções de declaração são uma maneira curta de instruir o programa a verificar a condição (também chamada de "asserção") e, se a condição não for Verdadeira, ocorrerá um erro.

Então, vamos ver como ficaria no "código normal"

if (typeof "string" === "array") { throw Error('Error: "string" !== "array"'); }

Com assertvocê pode simplesmente escrever:

assert(typeof "string" === "array")

No Javascript, não há assertfunção nativa , então você precisa usar uma de alguma biblioteca.

Para uma introdução simples, você pode verificar este artigo:

http://fredkschott.com/post/2014/05/nodejs-testing-essentials/

Espero que ajude.

Pavel
fonte
2

A asserção lança uma mensagem de erro se o primeiro atributo for falso e o segundo atributo é a mensagem a ser lançada.

console.assert(condition,message);

Existem muitos comentários dizendo que a asserção não existe no JavaScript, mas console.assert()é a função assert no JavaScript A idéia da asserção é descobrir por que / onde o erro ocorre.

console.assert(document.getElementById("title"), "You have no element with ID 'title'");
console.assert(document.getElementById("image"), "You have no element with ID 'image'");

Aqui, dependendo da mensagem, você pode encontrar qual é o erro. Essas mensagens de erro serão exibidas no console na cor vermelha, como se chamamos console.error();
Para ver mais funções no console, executeconsole.log(console);

Rahul
fonte
1

Respostas anteriores podem ser aprimoradas em termos de desempenho e compatibilidade.

Verifique uma vez se o Errorobjeto existe, se não o declare:

if (typeof Error === "undefined") {
    Error = function(message) {
        this.message = message;
    };
    Error.prototype.message = "";
}

Então, cada asserção verifica a condição e sempre lança um Errorobjeto

function assert(condition, message) {
    if (!condition) throw new Error(message || "Assertion failed");
}

Lembre-se de que o console não exibirá o número da linha de erro real, mas a linha da assertfunção, que não é útil para depuração.

Karl.S
fonte
1

Se você usar Webpack, você pode simplesmente usar a biblioteca afirmação node.js . Embora eles afirmem que "não se destina a ser uma biblioteca de asserções de uso geral", parece ser mais do que aceitável para asserções ad hoc, e parece que não existe nenhum concorrente no espaço do Node (o Chai foi projetado para testes de unidade).

const assert = require('assert');
...
assert(jqXHR.status == 201, "create response should be 201");

Você precisa usar o webpack ou o browserify para poder usá-lo, portanto, obviamente, isso só será útil se eles já estiverem no seu fluxo de trabalho.

amoe
fonte
1

Além de outras opções, como console.assert ou rolando por conta própria , você pode usar invariáveis . Tem algumas características únicas:

  • Ele suporta mensagens de erro formatadas (usando um %sespecificador).
  • Em ambientes de produção (conforme determinado pelo ambiente Node.js ou Webpack), a mensagem de erro é opcional, permitindo .js (um pouco) menores.
Josh Kelley
fonte
0

Conforme mencionado por TJ, não há assertno JavaScript. No entanto, existe um módulo de nó chamado assert , que é usado principalmente para teste . então, você pode ver código como:

const assert = require('assert');
assert(5 > 7);
yuval.bl
fonte