简体   繁体   中英

Assertion Error when logging.exception(error)

I have this function in a script called mymodule.py

import logging

def foo():
    try:
        raise ConnectionError('My Connection Error')
    except ConnectionError as ce:
        logging.exception(ce)

And I have the test for it called test_mymodule.py:

import unittest
import unittest.mock as um
import mymodule

class TestLoggingException(unittest.TestCase):

    @um.patch('mymodule.logging')
    def test_connection_error_correctly_logged_without_raising(self, mock_logging):
        mymodule.foo()

        mock_logging.assert_has_calls(
            [um.call(ConnectionError('My Connection Error'))]
        )

However, when running test_mymodule.py, the below assertion error is raised.

AssertionError: Calls not found.
Expected: [call(ConnectionError('My Connection Error'))]
Actual: [call(ConnectionError('My Connection Error'))]

Why is it thinking they are different and how could I work around this?

The problem is that two instances of ConnectionError , even if create with the same arguments, are not equal.

You create two instances in your code: in foo and in the um.call() .
However, those two instance are not the same, and are therefore not equal. You can illustrate that simply:

>>> ConnectionError("test") == ConnectionError("test")
False

One solution is to check which calls were made to the mockup. The calls are exposed through a variable called mockup_calls .
Something like this

class TestLoggingException(unittest.TestCase):

    @um.patch('mymodule.logging')
    def test_connection_error_correctly_logged_without_raising(self, mock_logging):
        mymodule.foo()

        print("Calls are: ", mock_logging.mock_calls)

        # Check that logging was called with logging.exception(ConnectionError("My Connection Error"))
        calls = mock_logging.mock_calls
        assert(len(calls) == 1)
        # Unpack call
        function_called, args, kwargs = calls[0]
        assert(function_called == "exception")
        connection_error = args[0]

        assert(isinstance(connection_error, ConnectionError))
        assert(connection_error.args[0] == "My Connection Error")  # This will depend on how ConnectionError is defined
        

What is tricky about this example is that it would work with types that evaluate equal even if they are not the same, like str ( "hi" == "hi" will yield True ), but not most classes.

Does it help?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM