Stack Exchange
Jest toThrow() method doesn't work properly
It fails even though the error thrown by my JS code seems to be correct. Relevant Jest code block:
 describe('operate', () => {
    test("works with addition", () => {
        expect(evaluate_expression("3+5")).toEqual(8);
    });
    test("works with substraction", () => {
        expect(evaluate_expression("128-29")).toEqual(99);
    });
    test("works with multiplication", () => {
        expect(evaluate_expression("25*5")).toEqual(125);
    });
    test("works with division", () => {
        expect(evaluate_expression("990/99")).toEqual(10);
    });
    test("division 0 is handled", () => {
        expect(evaluate_expression("5/0")).toThrow('Division by zero');
    });
});

JavaScript code:
function append_to_display(value) {
    if (start == false)
        document.getElementById('display').value += value;
    else {
        document.getElementById('display').value = value;
    };
};

function calculate() {
    try {
        const expression = document.getElementById('display').value;
        console.log(expression);
        const result = evaluate_expression(expression);
        document.getElementById('display').value = result;
        document.getElementById('current_value').textContent = result;
    } catch (error) {
        document.getElementById('display').value = 'Error';
    }
};

function evaluate_expression(expression) {
    const output_queue = [];
    const operator_stack = [];
    const operators = { '+': 1, '-': 1, '*': 2, '/': 2 };

    const tokens = expression.match(/([0-9]+|\+|\-|\*|\/)/g);

    tokens.forEach(token => {
        if (!isNaN(token)) {
            output_queue.push(parseFloat(token));
        } else if (token in operators) {
            while (
                operator_stack.length > 0 &&
                operators[token] <= operators[operator_stack[operator_stack.length - 1]]
            ) {
                output_queue.push(operator_stack.pop());
            }
            operator_stack.push(token);
        } else {
            throw new Error('Invalid expression');
        }
    });

    while (operator_stack.length > 0) {
        output_queue.push(operator_stack.pop());
    }

    const result_stack = [];
    output_queue.forEach(token => {
        if (!isNaN(token)) {
            result_stack.push(token);
        } else {
            const b = result_stack.pop();
            const a = result_stack.pop();
            switch (token) {
                case '+':
                    result_stack.push(a + b);
                    break;
                case '-':
                    result_stack.push(a - b);
                    break;
                case '*':
                    result_stack.push(a * b);
                    break;
                case '/':
                    if (b === 0) {
                        throw new Error('Division by zero'); // HERE IS THE PROBLEM
                    }
                    result_stack.push(a / b);
                    break;
                default:
                    throw new Error('Invalid operator');
            }
        }
    });

    if (result_stack.length !== 1) {
        throw new Error('Invalid expression');
    }

evaluate_expression() is called via calculate() on clicking the "=" button on the calculator.
The exact line in the JavaScript code is this:
    if (b === 0) {
         throw new Error('Division by zero'); // HERE IS THE PROBLEM
    }

I have tried to append rejects to expect here, but this doesn't work.

.rejects would only work if your function returned a promise. Re-read the docs carefully and think about control flow - when, in your current test, is evaluate_expression called?

@jonrsharpe Edited javascript code section to include the rest of the code. "evaluate_expression" is called by "calculate", which is called when "=" button is clicked on the calculator in the app.

That's not relevant to the test case, though, where evaluate_expression is called directly. You've successfully decoupled the logic from the UI, think about the control flow in the test. Or just do some basic research: https://stackoverflow.com/q/49027595/3001761.

In order to use Jest toThrow, you need to pass a function to expect, i.e, wrap the code you want to test in a function.
https://jestjs.io/docs/expect#tothrowerror

You must wrap the code in a function, otherwise the error will not be caught and the assertion will fail.

test("division 0 is handled", () => {
    expect(() => evaluate_expression("5/0")).toThrow('Division by zero');
});

