Reputation: 2449
I'm trying to run unit tests on a class that imports two other modules, and I'm trying to patch out those modules using mock
. One of these modules is instantiated in the class I'm testing, and I have not been able to patch it out. It appears that I have managed to patch out the other one.
What is the best way to patch out the sequence.processor
module in this code?
Directory structure
logger.py
parser/
__init__.py
docparser.py
sequence/
__init__.py
processor.py
tests/
testdocparser.py
/parser/docparser.py
import logger
from sequence.processor import Processor
class DocParser(object):
def __init__(self, reader_writer):
self.processor = Processor(reader_writer)
def write_and_parse(self, products):
logger.log(products)
self.processor.process(products)
/tests/testdocparser.py
import unittest
from mock import MagicMock, patch
from parser import docparser
class DocParserTests(unittest.TestCase):
def setUp(self):
self.mock_writer = MagicMock()
self.docparser = docparser.DocParser(self.mock_writer)
@patch("parser.docparser.logger") # This seems to be patched properly
@patch("parser.docparser.Processor") # This is not patched
def test_write_and_parse(self, mock_logger, mock_proc):
products = "products"
self.docparser.write_and_parse(products)
Upvotes: 0
Views: 372
Reputation: 2092
You patch Processor
in test_write_and_parse()
but it's instantiated in DocParser.__init__()
which is called from setUp()
.
This should work, though I haven't tested it:
class DocParserTests(unittest.TestCase):
def setUp(self):
self.mock_writer = MagicMock()
with patch('parser.docparser.Processor'):
self.docparser = docparser.DocParser(self.mock_writer)
@patch("parser.docparser.logger")
def test_write_and_parse(self, mock_logger):
products = "products"
self.docparser.write_and_parse(products)
I've used context manager instead of decorator to avoid changing setUp()
signature (adding an argument).
Also the order of mock arguments for test_write_and_parse() is incorrect in your code. Here's an excerpt from mock docs:
When you nest patch decorators the mocks are passed in to the decorated function in the same order they applied (the normal python order that decorators are applied). This means from the bottom up...
Correct order:
@patch("parser.docparser.logger") # This seems to be patched properly
@patch("parser.docparser.Processor") # This is not patched
def test_write_and_parse(self, mock_proc, mock_logger):
# ...
Of cource, it doesn't really matter in your particular case because mock_proc
and mock_logger
are not used later.
Upvotes: 1