Как я могу исправить параметр из функции, которая вызывает метод? - PullRequest
1 голос
/ 08 ноября 2019

Здравствуйте, я довольно новичок в модульном тестировании, и поэтому у меня возникла большая проблема с unittest.mock. Мой проект состоит из разных модулей. Мой первый модуль - General:

general.py


def do_something(item, collection): 
    # some more code that i want to test
    try:
        collection.insert_one(item)
    except:
        print("did not work")

Мой второй модуль ist my_module.py

mymodule.py

import general
from pymongo import MongoClient

client = MongoClient("localhost", 27017)
db = client['db']
collection = db['col']

item = 
  {
    "id": 1
  }



def method:
    general.do_something(item, collection)

Теперь я хочу протестировать метод do_something (item, collection) из general.py ипоэтому я хочу издеваться над collection.insert_one (item). Я не нашел возможного решения для этого. Я пробовал это с патчем, но моя проблема в том, что коллекция параметров (которая является коллекцией pymongo) является параметром, который вызывает функцию. Как теперь я могу смоделировать collection.insert_one?

Моя цель - извлечь collection.insert_one и установить в него MagicMock. И этот Magic Mock должен иметь возможность сбоя, чтобы проверить, работает ли исключающая часть, или не потерпеть крах, чтобы проверить, работает ли пробная часть.

TestGeneral.py
import unnittest

class TestGeneral(unittest.TestCase):

    @patch()
    def test_general():





Заранее спасибо! :)

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

Если вам по какой-то причине пришлось использовать mock, этот метод мог бы работать

TestGeneral.py import unnittest

class TestGeneral(unittest.TestCase):

    @mock.patch('{your path}.my_module.MongoClient')
    def test_general_success(mock_mongo):
        mock_mongo.return_value = {'db': None, 'col': collection()}
        assert general.do_something(None, None)  # None here since the collection is mocked anyway

    @mock.patch('{your path}.my_module.MongoClient')
    def test_general_failure(mock_mongo):
        mock_mongo.return_value = {'db': None, 'col': collection(fail=True)}
        with self.assertRaises(Exception): 
            general.do_something(None, None))

class collection:
    def __init__(self, fail=False):
        self.fail = fail

    def insert_one(self, item):
        if self.fail:
            raise Exception
        return True

Недостатком этого является то, что вы теперь высмеяли весь MongoDBЭто означает, что любое другое его использование (т. е. клиент) также будет высмеяно

1 голос
/ 08 ноября 2019

На самом деле здесь вам не нужен макет, вы можете просто создать класс с похожей функциональностью.

TestGeneral.py
import unnittest

class TestGeneral(unittest.TestCase):

    def test_general_success():
        assert general.do_something(collection(), None)

    def test_general_failure():
        with self.assertRaises(Exception): 
            general.do_something(collection(fail=True), None))

class collection:
    def __init__(self, fail=False):
        self.fail = fail

    def insert_one(self, item):
        if self.fail:
            raise Exception
        return True

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

...