Mr-Pepe
Mr-Pepe

Reputation: 87

How can I wrap unittest's assertRaises in another context manager?

I want to wrap the unittest.TestCase().assertRaises context manager with another context manager but struggle to find a solution. Here is my approach:

import unittest
from contextlib import contextmanager


@contextmanager
def wrapper():
    print("Before assertion")
    yield unittest.TestCase().assertRaises(ValueError)
    print("After assertion")


with wrapper():
    raise ValueError()

However, the ValueError is not caught by assertRaises and the output of running the code is:

Before assertion
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    raise ValueError()
ValueError

How can I wrap assertRaises in another context manager such that it catches the expected exception but gives me the chance to do something afterwards ("After assertion" gets printed)? Can I do something like the following to catch errors that are not caught by the assertRaises?

@contextmanager
def wrapper():
    try:
        print("Before assertion")
        yield unittest.TestCase().assertRaises(ValueError)
        print("After assertion")
    except Exception:
        print("Did not raise ValueError!")

Upvotes: 0

Views: 126

Answers (1)

Samwise
Samwise

Reputation: 71517

Your context manager yields another context manager, so you need another with:

import unittest
from contextlib import contextmanager


@contextmanager
def wrapper():
    print("Before assertion")
    yield unittest.TestCase().assertRaises(ValueError)
    print("After assertion")


with wrapper() as another_manager:
    with another_manager:
        raise ValueError()

What you probably want to do instead of yielding the context manager is to put the assertRaises context inside your wrapper, and yield (None) from inside that:

import unittest
from contextlib import contextmanager


@contextmanager
def wrapper():
    print("Before assertion")
    with unittest.TestCase().assertRaises(ValueError):
        yield
    print("After assertion")


with wrapper():
    raise ValueError()

Upvotes: 1

Related Questions