ModuleNotFoundError при попытке использовать mock.patch для метода - PullRequest
2 голосов
/ 05 апреля 2020

Мой тестовый модуль pytest продолжает выдавать ошибку ModuleNotFoundError: No module name billing.

Как ни странно, метод send_invoices в модуле биллинга может быть вызван при удалении оператора исправления. Почему mock.patch не может найти модуль выставления счетов и исправить метод, если это так?

billing.py

import pdfkit
from django.template.loader import render_to_string
from django.core.mail import EmailMessage
from projectxapp.models import User

Class Billing:

  #creates a pdf of invoice. Takes an invoice dictionary
  def create_invoice_pdf(self, invoice, user_id):
    #get the html of the invoice
    file_path ='/{}-{}.pdf'.format(user_id, invoice['billing_period'])
    invoice_html = render_to_string('templates/invoice.html', invoice)
    pdf = pdfkit.from_file(invoice_html, file_path)
    return file_path, pdf

  #sends invoice to customer
  def send_invoices(self, invoices):
    for user_id, invoice in invoices.items():
            #get customers email
            email = User.objects.get(id=user_id).email
            billing_period = invoice['billing_period']
            invoice_pdf = self.create_invoice_pdf(invoice, user_id)
            email = EmailMessage(
                'Statement of credit: {}-{}'.format(user_id, billing_period),
                'Attached is your statement of credit.\
                This may also be viewed on your dashboard when you login.',
                'no-reply@trevoe.com',
                [email],
            ).attach(invoice_pdf)

            email.send(fail_silently=False)

        return True

test.py

from mock import patch
from projectxapp import billing

@pytest.mark.django_db
def test_send_invoice():
  invoices = {
    1: {
        'transaction_processing_fee': 2.00,
        'service_fee': 10.00,
        'billing_period': '2020-01-02'
    },
    2: {
        'transaction_processing_fee': 4.00,
        'service_fee': 20.00,
        'billing_period': '2020-01-02'
    }
 }

  with patch('services.billing.Billing().create_invoice_pdf') as p1:
    p1.return_value = '/invoice.pdf'
    test = billing.Billing().send_invoices(invoices)

  assert test == True

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

При использовании patch вы должны указать полный путь к модулю, включая имена пакетов. Также не используйте круглые скобки в пути. Измените атрибут return_value объекта Mock, чтобы настроить возвращаемое значение вызова объекта:

with patch('projectxapp.billing.Billing.create_invoice_pdf') as p1:
    p1.return_value = '/invoice.pdf'
    test = billing.Billing().send_invoices(invoices)
0 голосов
/ 27 апреля 2020

Решение

Поскольку я уже импортировал модуль метода, который мне нужно было исправить. Мне не нужно было использовать полный путь, включая имя пакета.

Изменено

patch('projectxapp.billing.Billing.create_invoice_pdf')

на этот

patch('billing.Billing.create_invoice_pdf')

Из Django документов:

target должен быть строкой в ​​форме 'package.module.ClassName'. Цель импортируется, а указанный объект заменяется новым, поэтому цель должна быть импортирована из среды, из которой вы вызываете patch (). Цель импортируется при выполнении декорированной функции, а не во время декорирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...