0

Let's say I have some class:

class Worker: _processor: Processor def set_processor(self, processor: Processor): self._processor = processor def start_work(self, data: bytes): self._processor.parse(data) 

It's pretty simple to test set_processor method, smth like that:

def test_set_processor(): mock_processor = Mock() worker = Worker() worker.set_processor(mock_processor) assert worker._processor == mock_processor 

We just pass mock into set_processor method and check if self._processor equals mock now.

But how can I test start_work method? I want to be sure that self._processor will be called with data? If I try to patch _processor attribute I'm getting error.

3
  • Why do you need to patch anything? You can test this whole thing in one go: pass the mock to the set method, call the other method and assert the mock got exercised as expected. Commented Dec 5, 2019 at 20:15
  • Yes, sounds good. But I think it's not bad idea to test separate every method. Now I solved with set _processor to mock directly: worker._processor = Mock(). And then call method and check if mock were called. Commented Dec 5, 2019 at 20:26
  • But then you're interfering with internal implementation details as part of the test. Test through the public API. Commented Dec 5, 2019 at 20:27

1 Answer 1

1

Here is the unit test solution:

worker.py:

from typing import Any Processor = Any class Worker: _processor: Processor def set_processor(self, processor: Processor): self._processor = processor def start_work(self, data: bytes): self._processor.parse(data) 

test_worker.py:

import unittest from worker import Worker from unittest.mock import Mock class TestWorker(unittest.TestCase): def test_set_processor(self): mock_processor = Mock() worker = Worker() worker.set_processor(mock_processor) assert worker._processor == mock_processor worker.start_work(b'') mock_processor.parse.assert_called_once_with(b'') if __name__ == '__main__': unittest.main() 

Unit test result with 100% coverage:

. ---------------------------------------------------------------------- Ran 1 test in 0.001s OK (venv) ☁ python-codelab [master] ⚡ coverage report -m Name Stmts Miss Cover Missing ------------------------------------------------------------------------- src/stackoverflow/59202648/test_worker.py 13 0 100% src/stackoverflow/59202648/worker.py 8 0 100% ------------------------------------------------------------------------- TOTAL 21 0 100% 

Source code: https://github.com/mrdulin/python-codelab/tree/master/src/stackoverflow/59202648

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.