331

What does assert mean in JavaScript?

I’ve seen something like:

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

And would like to know what the method assert() does.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
frrlod
  • 6,475
  • 8
  • 31
  • 37

17 Answers17

466

There is no standard assert in JavaScript itself. Perhaps you're using some library that provides one; for instance, if you're using Node.js, perhaps you're using the assertion module. (Browsers and other environments that offer a console implementing the Console API provide console.assert.)

The usual meaning of an assert function is to throw an error if the expression passed into the function is false; this is part of the general concept of assertion checking. Usually assertions (as they're called) are used only in "testing" or "debug" builds and stripped out of production code.

Suppose you had a function that was supposed to always accept a string. You'd want to know if someone called that function with something that wasn't a string (without having a type checking layer like TypeScript or Flow). So you might do:

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

...where assert would throw an error if the condition were false.

A very simple version would look like this:

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

Better yet, make use of the Error object, which has the advantage of collecting a stack trace and such:

function assert(condition, message) {
    if (!condition) {
        throw new Error(message || "Assertion failed");
    }
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 8
    ...getting uppity about types in JS? I'd argue that's one of the worst reasons to `assert`. – cHao Mar 09 '13 at 17:05
  • 182
    @cHao: There are valid use cases. It was just the first example that came to mind. The example isn't the point. The concept of assertions is the point. – T.J. Crowder Mar 09 '13 at 17:05
  • 5
    something that I've added to my code inside the `if(!condition)` is setting `var throwError=true;` then `debugger;` then wrap the throw section in an `if(throwError)`. That way, if I have the debugger open, it'll break, and if I so desire I can set `throwError` to false and then examine all the scopes while stepping out. – Rick Jun 04 '15 at 17:20
  • 13
    @Rick if you use Chrome DevTools, you can simply enable "Pause on Uncaught Exceptions" in the Sources tab and it will automatically break at the `throw`. That way you don't need the `debugger;` statement. See https://developer.chrome.com/devtools/docs/javascript-debugging#pause-on-exceptions for more. – Vicky Chijwani Dec 30 '15 at 12:14
  • Here's a slightly simpler version of T.J.'s assert (which could be made even simpler by using an arrow function): `function (condition, message) { if (condition) return; message = message || 'Assertion failed'; throw typeof Error !== 'undefined' ? new Error(message) : message; // Very old browsers lacks Error }` – machineghost Apr 01 '16 at 17:41
  • 1
    @machineghost: I don't see how that's "simpler," you've just traded `if` for a conditional operator. Anyway, in today's world, I wouldn't bother to support engines that don't have `Error`. – T.J. Crowder Apr 02 '16 at 10:33
  • I did say "slightly" :) – machineghost Apr 04 '16 at 17:06
  • Array.every() sort of / kind of "asserts" – gawkface Aug 23 '20 at 09:41
  • @harshvchawla - `every` just returns a boolean, it doesn't assert anything. – T.J. Crowder Aug 23 '20 at 10:21
  • @T.J.Crowder thanks for the reply! Doesn't `every` _pass a test_ to return the boolean? – gawkface Aug 26 '20 at 17:57
  • @harshvchawla - Yes. Which isn't what `assert` does. `assert` also does a test, but if the test doesn't pass, it throws an assertion error. – T.J. Crowder Aug 27 '20 at 07:37
  • @T.J.Crowder yeah there is no "exception thrown" in `every`; that's why i wrote "sort of/kind of" does the "testing a condition" hehe. – gawkface Aug 27 '20 at 13:42
  • @harshvchawla - You're entitled to your own opinion of course, but I don't see any relationship between `every` and `assert`. They do completely different things. They just both happen to involve a boolean value. Anyway, no point in an ongoing discussion. – T.J. Crowder Aug 27 '20 at 13:45
  • @T.J.Crowder I agree on all counts with you, even of having of differing opinions, I guess I will think more on it. Thanks for the discussion! – gawkface Aug 28 '20 at 15:28
  • Now we have `console.assert()` on client side and assert module on server-side – 27px Dec 14 '20 at 02:29
  • 1
    @27px - Good point, I've updated the answer to call that out and also call out Node.js's assertion module. – T.J. Crowder Dec 14 '20 at 08:04
176

If using a modern browser or nodejs, you can use console.assert(expression, object).

For more information:

Pang
  • 9,564
  • 146
  • 81
  • 122
joaoprib
  • 1,878
  • 1
  • 13
  • 12
  • 65
    FYI, this acts more like `console.error` in that the code continues to execute. – Daniel Sokolowski Oct 25 '14 at 03:10
  • 12
    @DanielSokolowski, Exactly. `console.assert` is not so good unless it has the same behavior as `throw`. – Pacerier May 23 '15 at 15:50
  • 30
    The reason execution continues after `console.assert` is because assertions are not error handling functions. They are designed for code correctness checking during development only. Traditionally they are completely disabled in production environments to avoid live systems terminating because of something trivial. The browser is deemed to be a production environment, so `console.assert` does not terminate execution there. If you are relying on assertions to stop execution then you should be using proper error handling instead, as this is not what assertions are meant for. – Malvineous Sep 10 '16 at 02:37
  • 11
    @RonBurk: Language designers decided "what assertions are meant for". In [C++](http://www.cplusplus.com/reference/cassert/assert/) _[an assertion] is designed to capture programming errors, not user or run-time errors, since it is generally disabled after a program exits its debugging phase._ [PHP](http://php.net/manual/en/function.assert.php) says _As a rule of thumb your code should always be able to work correctly if assertion checking is not activated._ The passive voice was not meant to give authority to a personal preference, but rather to report what is widely accepted general practice. – Malvineous Mar 07 '17 at 07:53
  • 3
    @Malvineous well, no, assertions are more often not part of the language (e.g. C, c++) at all. And assertions are a *concept*, not the particular invention of a particular language. So, "language designers" don't enter into the picture of what assertions are or what they "should" be used for at all. Language designers can tell you all sorts of things, but they didn't invent modularity, or interfaces, or any language-independent concept. See the 1st edition of The C++ Programming Language for advice contradicted in the latest edition, for example. – Ron Burk Mar 07 '17 at 15:54
  • 3
    @Malvineous "In C++ [an assertion] is designed to capture programming errors, not user or run-time errors, since it is generally disabled after a program exits its debugging phase." This is an unfortunately popular point of view that rests on the unrealistic assumption that after the debugging phase is over, there are no more programming errors and so it's fine to simply remove the guard rails. This point of view is not universally held and is indeed offensive and frightening to many. So unless you want to rile people, it might be helpful to frame it more cautiously. – Don Hatch Apr 05 '17 at 22:38
  • 6
    @Don: Point taken but I was just quoting from the linked pages. I do believe assertions should be treated as if they can be disabled, if only because your code might one day be used by someone who thinks it is safe to do so. If assertions are critical to your code, then I think they really should be upgraded to proper error checking rather than relying on a debugging method that is not always guaranteed to terminate execution. Not to mention that having your code repeatedly die in a production environment when it could just return an error and continue might cause more stress than it's worth! – Malvineous Apr 07 '17 at 07:14
  • assertions are and should be part of languages, as a strong design contract about what an algorithm is supposed to do and to explicitly delimit what it implements and what it does not. Javascript for example allows extending functions by adding new parameters, but most often these extra parameters are not checked (as they are not used at all), you may/should add assertions in Javascript functions for these unspecified parameters because this can cause later usage bugs (calling a function with extra parameters without the expected effect in implementation, no exception and false results!). – verdy_p Oct 08 '18 at 21:24
  • But Javascript (also PHP) is extremely permissive and allows binding all sort of parameters including new untested types. This is both good (easy extensibility) and bad (lack of version tracking in implementations). That's why other languages (like Eiffel or even Java) are still popular and Javascript/ECAMScript programs is so difficult to proove they are correct and do what they were designed for. – verdy_p Oct 08 '18 at 21:27
  • So Javascript still lacks a correct way to describe the contracts and limits of implementations. Corba/.Net/Java have a very useful concept of "interfaces" that Javascript is still severely missing. So you need "assert()" even in production Javascript code ! On the opposite, "asserts" can be safely removed in production code written in Eiffel and Java (and a lot of optimizations are possible at run time that are not possible in Javascript with run-time checks everywhere still not capable of tracking all bugs and implementations limits). – verdy_p Oct 08 '18 at 21:30
  • 1
    I think it's worth mentioning that, if you have Chrome dev tools open, then **`console.assert` will throw an error**, so it is rather useful for debugging on the client-side – woojoo666 Apr 09 '19 at 06:29
  • 1
    @Malvineous: Also, checks can be very expensive to execute. Once I was developing a self balancing binary tree. I had many assertions that checked the whole tree to see if it was correctly balanced. In C standard library, assert is a macro that becomes nothing when compiling without debug flags. – André Caldas May 19 '19 at 00:19
  • @AndréCaldas: Yes this was exactly my point - assertions are often disabled at run time to avoid the performance penalty. Any issues they might detect should have been picked up at the testing stage and won't occur in production if the programmer has written their tests properly. – Malvineous May 19 '19 at 07:48
  • 1
    @Malvineous - but console.assert is missing the *other* side of what "assertions" typically do: be **able** to throw an exception. Not in production, but in near-production testing. I like wikipedia's quote *"if the impossible occurs, then something fundamental is clearly wrong with the program."* That's the proper use of assertions: something that should *never* happen. If it does happen, its important to stop, and gather as much info as possible. Not just log a message and continue. – ToolmakerSteve Nov 01 '19 at 13:48
36

The other answers are good: there isn't an assert function built into ECMAScript5 (e.g. JavaScript that works basically everywhere) but some browsers give it to you or have add-ons that provide that functionality. While it's probably best to use a well-established / popular / maintained library for this, for academic purposes a "poor man's assert" function might look something like this:

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
Vitaly Zdanevich
  • 13,032
  • 8
  • 47
  • 81
jacobq
  • 11,209
  • 4
  • 40
  • 71
  • See http://stackoverflow.com/questions/15313418/javascript-assert#comment48915308_17054137 – Pacerier May 23 '15 at 15:51
  • BTW, one could easily modify this so that it only throws an error in development environments (e.g. by wrapping in another if / adding another conditional) and otherwise does nothing or only prints a warning. Personally, my opinion is that assertions should only be in test code (e.g. checking whether expected & actual results match); in production code they should either be superfluous (guaranteed correct by design) and thus removed or only for guarding user/external input in which case they can be replaced by sanitizing logic & standard exception handling (e.g. `try`, `catch`, `throw`) – jacobq Jan 31 '19 at 19:49
  • @jacobq This is not appropriate for the purpose of `assert`. Assert is a contract, intended to never be false by design of the program. It would be wrong to catch asserts except in a test. That's the only reason why asserts can be catched. You cannot assert user or client-side input. It doesn't make sense like blaming attackers for the program bug. Even an exception would be bad because user input is not an exceptional situation, not an error. It's like blaming the user/client-side for a program fault. This principle is language-independent. Only bad handling or sanitizing can be blamed. – ChrisoLosoph Oct 26 '21 at 13:41
  • @ChrisoLosoph Could you clarify what you think is not appropriate? Note that this implementation is a "[poor man's](https://www.wordnik.com/words/poor%20man's) assert", i.e. an approximation, and I'm not suggesting that assert should be used in place of exception handling or logic. I did mention that if they are being used for things like guarding input then there are other alternatives (e.g. if/else logic or try/catch exception handling) that are probably more suitable. – jacobq Nov 01 '21 at 10:42
  • I'm sorry for the confusion. I wasn't refering to your answer but to the last statement of your previous comment :-) . – ChrisoLosoph Nov 02 '21 at 18:19
11

assert() is not a native javascript function. It is a custom function someone made. You will have to look for it on your page or in your files and post it for anybody to help determine what it's doing.

CrayonViolent
  • 32,111
  • 5
  • 56
  • 79
7

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

it is for testing JavaScript. Amazingly, at barely five or six lines, this code provides a great level of power and control over your code, when testing.

The assert function accepts two parameters:

outcome: A boolean, which references whether your test passed or failed

description: A short description of your test.

The assert function then simply creates a list item, applies a class of either “pass” or “fail,” dependent upon whether your test returned true or false, and then appends the description to the list item. Finally, that block of coded is added to the page. It’s crazy simple, but works perfectly.

Amrendra
  • 2,019
  • 2
  • 18
  • 36
6

If the assertion is false, the message is displayed. Specifically, if the first argument is false, the second argument (the string message) will be be logged in the developer tools console. If the first argument is true, basically nothing happens. A simple example – I’m using Google Developer Tools:

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.');
Crazy Cat
  • 1,332
  • 15
  • 19
4

It probably came with a testing library that some of your code is using. Here's an example of one (chances are it's not the same library as your code is using, but it shows the general idea):

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

Matt Browne
  • 12,169
  • 4
  • 59
  • 75
4

Word or function "assert" is mostly used in testing parts of application.

Assert functions are a short way of instructing the program to check the condition (also called "assertion") and if the condition is not True, it will throw error.

So let's see how it would look like in "normal code"

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

With assert you can simply write:

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

In Javascript, there's no native assert function, so you have to use one from some library.

For simple introduction, you can check this article:

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

I hope it helps.

Pavel
  • 193
  • 2
  • 9
4

Assertion throws error message if first attribute is false, and the second attribute is the message to be thrown.

console.assert(condition,message);

There are many comments saying assertion does not exist in JavaScript but console.assert() is the assert function in JavaScript The idea of assertion is to find why/where the bug occurs.

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

Here depending on the message you can find what the bug is. These error messages will be displayed to console in red color as if we called console.error();

You can use assertions to test your functions eg:

console.assert(myAddFunction(5,8)===(5+8),"Failed on 5 and 8");

Note the condition can be anything like != < > etc

This is commonly used to test if the newly created function works as expected by providing some test cases and is not meant for production.

To see more functions in console execute console.log(console);

27px
  • 430
  • 5
  • 16
3

In addition to other options like console.assert or rolling your own, you can use invariant. It has a couple of unique features:

  • It supports formatted error messages (using a %s specifier).
  • In production environments (as determined by the Node.js or Webpack environment), the error message is optional, allowing for (slightly) smaller .js.
Community
  • 1
  • 1
Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
3

Java has a assert statement, the JVM disables assertion validation by default. They must be explicitly enabled using command line argument -enableassertions (or its shorthand -ea),

while JavaScript supports console.assert(), it's just a logging method and won't interrupt current procedure if assertion failed.

To bring things together and satisfy various needs, here is a tiny js assertion lib.

globalThis.assert = (()=> {
  class AssertionError extends Error {
    constructor(message) {
      super(message);
      this.name = 'AssertionError';
    }
  }
  let config = {
    async: true,
    silent: false
  };
  function assert(condition, message = undefined) {
    if (!condition) {
      if (config.silent) {
        //NOOP
      } else if (config.async) {
        console.assert(condition, message || 'assert');
      } else {
        throw new AssertionError(message || 'assertion failed');
      }
    }
  }
  assert.config = config;
  return assert;
})();


/* global assert */
Object.assign(assert.config, {
  // silent: true, // to disable assertion validation
  async: false, // to validate assertion synchronously (will interrupt if assertion failed, like Java's)
});

let items = [
  {id: 1},
  {id: 2},
  {id: 3}
];
function deleteItem(item) {
  let index = items.findIndex((e)=> e.id === item.id);
  assert(index > -1, `index should be >=0, the item(id=${item.id}) to be deleted doesn't exist, or was already deleted`);
  items.splice(index, 1);
}

console.log('begin');
deleteItem({id: 1});
deleteItem({id: 1});
console.log('end');
fuweichin
  • 1,398
  • 13
  • 14
3

Node.js has an assert function you can import:

const assert = require('assert')

It works as one would expect, in that assert(false) throws an error, and assert(false, message) throws an error with a message.

The other answers have already pointed out that JS itself has no native assert function, and that remains true as of this writing (April 2021).

Asker
  • 1,299
  • 2
  • 14
  • 31
2

Previous answers can be improved in terms of performances and compatibility.

Check once if the Error object exists, if not declare it :

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

Then, each assertion will check the condition, and always throw an Error object

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

Keep in mind that the console will not display the real error line number, but the line of the assert function, which is not useful for debugging.

Karl.S
  • 2,294
  • 1
  • 26
  • 33
2

If you use webpack, you can just use the node.js assertion library. Although they claim that it's "not intended to be a general purpose assertion library", it seems to be more than OK for ad hoc assertions, and it seems no competitor exists in the Node space anyway (Chai is designed for unit testing).

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

You need to use webpack or browserify to be able to use this, so obviously this is only useful if those are already in your workflow.

amoe
  • 4,473
  • 4
  • 31
  • 51
1

As mentioned by T.J., There is no assert in JavaScript. However, there is a node module named assert, which is used mostly for testing. so, you might see code like:

const assert = require('assert');
assert(5 > 7);
yuval.bl
  • 4,890
  • 3
  • 17
  • 31
-1

assert() is the assert function in JavaScript. The main idea of assertion is to find why/where the bug occurs.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Lies Feb 09 '22 at 10:46
-1

Chrome devtools support console.assert You can open devtools and create a snippet in devtools-source-navigator-Snippets. And code some code... and run the snippet...

Youth overturn
  • 341
  • 5
  • 7
  • Your answer doesn't add anything to this question post: existing other answers have mentioned `console.assert` already. – Dai Mar 02 '22 at 08:55