Evan
Evan

Reputation: 2556

How to check exception cause using pytest raises?

I'd like to test that an exception is raised from another exception type.

import pytest


def throw_with_cause():
  raise Exception("Failed") from ValueError("That was unexpected.")
 
with pytest.raises(Exception): # from ValueError???
  throw_with_cause()

I'm surprised not to see a way to inspect the exception chain in the pytest raises docs. https://docs.pytest.org/en/6.2.x/reference.html#pytest-raises

Is there a clean way to do this using ptyest raises?

Upvotes: 7

Views: 10668

Answers (2)

XU Weijiang
XU Weijiang

Reputation: 78

Just encounter the same problem. Here is my solution.

@contextmanager
def raises_with_cause(exception_type, match=None):
    try:
        yield
    except Exception as e:
        cause = e
        while cause.__cause__:
            cause = cause.__cause__
        assert isinstance(cause, exception_type), f"unexpected cause: {cause}"
        assert not match or re.search(match, str(cause)), f"unexpected cause message: {cause}"
    else:
        raise AssertionError(f"expected exception {exception_type} not raised")

Upvotes: 0

Evan
Evan

Reputation: 2556

Until something more readable comes along, I'm doing the following.

import pytest

def throw_with_cause():
   raise Exception("Failed") from ValueError("That was unexpected.")


def test_throws_with_cause():
    with pytest.raises(Exception, match="Failed") as exc_info:
        throw_with_cause()
    assert type(exc_info.value.__cause__) is ValueError

Upvotes: 7

Related Questions