0

I am trying to unit test method that calls logging.info three times – first time it's logging local variables for the method, another two times it's logging messages that get triggered in case a certain condition is fulfilled.

In one of my test cases, logging.info gets called only once – to log local variables. The other two calls are not supposed to happen. I'm trying to include that in my unit tests but using unittest.mock.Mock.assert_not_called() is quite naturally out of question because my logging.info gets called once. (However, I can't test logging.info message for local variables.)

class Test_create_s3_file(unittest.TestCase):
    ...
    
    def setUp(self):
        self.LOGGER = logging
        ...

    def test_success_basic(self):
        # Mocks
        self.LOGGER.info = MagicMock()
        ...
        # Calls
        ...
        self.LOGGER.info.assert_not_called()
        # Does not work because it has one call for local variables
Myklebost
  • 59
  • 8
  • Asserting that something is not called is not usually very helpful. Ask yourself if this test you have in mind can ever fail. If not, then it isn't a useful test. In your case, an assertion that a `info()` is called exactly once with the desired parameters will guarantee that it isn't called with the incorrect parameters. – Code-Apprentice Aug 23 '22 at 18:44
  • @Code-Apprentice It can fail in case condition that triggers `logging.info` for the other two info messages would be triggered. I see it similarly like if you have `logging.warning` message in your code but your test case is not supposed to trigger warning message, you would include something like `self.LOGGER.warning.assert_not_called()`. – Myklebost Aug 23 '22 at 18:48
  • 1
    `assert_not_called()` asserts that a method was never called. You cannot use it for your scenario where a method is called once. – Code-Apprentice Aug 23 '22 at 18:55

1 Answers1

2

.has_calls takes a list of call objects. You can specify exactly which calls a mock is supposed to have this way.

If it is really only loggers that are relevant to you, you can make use of assertLogs as well.

Daniil Fajnberg
  • 12,753
  • 2
  • 10
  • 41