I'd like to patch some external packages used in a module I'm testing. Please do take a look at my code:
src/Notifiers.py
from abc import ABC, abstractmethod
from pathlib import PureWindowsPath
from smtplib import *
from datetime import datetime
from email.mime.text import MIMEText
import logging
import schedule
class Notifier(ABC):
def __init__(self, name):
self._logger = logging.getLogger(__name__)
self._name = name
@abstractmethod
def send_notification(self, msg):
pass
def set_logger(self, root_name):
my_logger_name = root_name + '.' + self._name
self._logger = logging.getLogger(my_logger_name)
self._logger.setLevel(logging.DEBUG)
class EmailNotifier(Notifier):
def __init__(self, name, host, port, user, passwd, receivers):
super().__init__(name)
self._host = host
self._port = port
self._username = user
self._password = passwd
self._receivers = receivers
def send_notification(self, lines):
self._logger.debug('Rozpoczynam wysylanie maila')
msg = MIMEText('\n'.join(lines))
msg['Subject'] = 'SIMail powiadomienie'
msg['From'] = 'SIMail kontrola routerow'
msg['To'] = ", ".join(self._receivers)
msg['Date'] = datetime.now().strftime('%a, %b %d, %Y at %I:%M %p')
try:
smtp_obj = SMTP(self._host,
self._port)
smtp_obj.starttls()
smtp_obj.login(self._username,
self._password)
smtp_obj.send_message(msg)
self._logger.info('Sent notification emails')
except SMTPRecipientsRefused:
print("Nobody was an email sent to")
except SMTPHeloError:
print("Server didnt respond for hello")
except SMTPSenderRefused:
print("Server refused sender")
The above code contains module I'd like to test. Please notice that EmailNotifier uses libraries like MIMEText and SMTP I will need to mock during the tests.
Now, I'll show you my test case: tests/unit/Notifiers_test.py
from mock import patch
from unittest import TestCase
from Notifiers import *
class EmailNotifierTest(TestCase):
@patch('Notifiers.email.mime.text.MIMEText')
@patch('Notifiers.smtplib.SMTP')
def test_send_notification(self, mock_smtp, mock_mime):
"""
Przypadek:
Wysyłamy powiadomienie email
Oczekiwane:
EmailNotifier nie może się wysypać
"""
mock_smtp.side_effect = lambda: None
name = 'test_name'
host = 'test_host'
port = 123
user = 'test-user'
passwd = 'test-passwd'
receivers = ('abc@def.gh', 'ijk@lmn.op')
notifier = EmailNotifier(name, host, port, user, passwd, receivers)
lines = ('1. This is line number one', '2. This is line number two')
notifier.send_notification(lines)
mock_mime.assert_called_with('\n'.join(lines))
The problem is I need to patch MIMEText used in EmailNotifier, which I test in another module, that is, Notifiers_test. But when I try to patch, I'm getting error:
F Notifiers_test.py:7 (EmailNotifierTest.test_send_notification) ........\AppData\Local\Programs\Python\Python37-32\lib\site-packages\mock\mock.py:1297: in patched arg = patching.enter() ........\AppData\Local\Programs\Python\Python37-32\lib\site-packages\mock\mock.py:1353: in enter self.target = self.getter() ........\AppData\Local\Programs\Python\Python37-32\lib\site-packages\mock\mock.py:1523: in getter = lambda: _importer(target) ........\AppData\Local\Programs\Python\Python37-32\lib\site-packages\mock\mock.py:1210: in _importer thing = _dot_lookup(thing, comp, import_path)
thing = , comp = 'smtplib' import_path = 'Notifiers.EmailNotifier.smtplib'
def _dot_lookup(thing, comp, import_path): try: return getattr(thing, comp) except AttributeError: __import__(import_path)E ModuleNotFoundError: No module named 'Notifiers.EmailNotifier'; 'Notifiers' is not a package
........\AppData\Local\Programs\Python\Python37-32\lib\site-packages\mock\mock.py:1199: ModuleNotFoundError
I tried to skip Notifiers in my patch src, but, then my objects wasn't patched at all. Can you tell me how to do it properly? I'm using PyCharm and src is set as Source directory.
I also attach my directories tree:

Aucun commentaire:
Enregistrer un commentaire