Невозможно проверить глобальное значение в фиктивной функции с помощью mock_open () - PullRequest
2 голосов
/ 13 июня 2019

Я пытаюсь использовать mock_open() для проверки моего приложения. Чтение поддельного файла с использованием декоратора патчей и side_effect , но я не могу проверить глобальное значение, установленное из функции в разделе тест. Работает только тогда, когда из функции возвращается значение.

Мой фрагмент кода приложения выглядит примерно так:

#!/usr/bin/env python
 # -*- coding: utf-8 -*-

thresh_dict = {}
allowed_san_dict = {}
max_eval_count = ""
clear_eval_count = ""

def generate_cfg_thresh_map():
    """ For generating a mapping table containing the thresholds for each of the
    production devices. The file is read one line at a time and split on whitespace
    to get the individual fields
    """

    global allowed_san_dict
    global max_eval_count
    global clear_eval_count
    try:
        with open ('/opt/config/pwr_thresh_cfg', 'r') as fh:
            for line in fh:
                split_line = line.split()
                if line.startswith("ENTRY_THRESH_COUNT"):
                    max_eval_count = int(split_line[1])
                elif line.startswith("EXIT_THRESH_COUNT"):
                    clear_eval_count = int(split_line[1])
                else:
                    thresh_dict[split_line[0]]  = [int(split_line[1]), int(split_line[2]), int(split_line[3])]
                    allowed_san_dict[split_line[0]] = int(split_line[4])

    except Exception as error:
        log_to_journal('read failed from pwr_thresh_cfg')

и файл test_app.py выглядит как

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Include require py.test libraries for the suite to run
import unittest
import pytest
import mock

import app

from mock import patch, mock_open

class ReportMonitor(unittest.TestCase):
    def test_generate_cfg_thresh_map(self):
        with patch('app.open', mock_open(read_data='ENTRY_THRESH_COUNT 200')) as _:
            app.generate_cfg_thresh_map()
            assert app.max_eval_count == 200
            print('value for %s' % (app.max_eval_count))
            print('value for %s' % (app.generate_cfg_thresh_map()))

Проблема в том, что я хочу установить значение max_eval_count, установленное в функции generate_cfg_thresh_map(). Поскольку значение задается в глобальной переменной и не возвращается из функции, я не могу подтвердить значение в моем тестовом примере. Я не могу использовать return из функции, то есть вообще не изменять код приложения.

Как бы я это сделал? то есть запустите тестируемую функцию и проверьте значение, установленное функцией для тестовой строки, и подтвердите случай модульного теста в зависимости от значения, установленного функцией.

1 Ответ

1 голос
/ 13 июня 2019

Цитирование mock_open документов :

read_data - строка для методов read(), readline() и readlines()дескриптор файла для возврата.Вызовы этих методов будут принимать данные из read_data до тех пор, пока они не будут исчерпаны.

Это означает, что read_data не будет вызываться при повторении итеративного объекта файла.Простое решение состоит в том, чтобы изменить реализацию функции generate_cfg_thresh_map на:

def generate_cfg_thresh_map():
    ...
    try:
        with open ('/opt/config/pwr_thresh_cfg', 'r') as fh:
            <b>for line in fh.readlines():</b>
                ...

Если вы не можете изменить функцию, в качестве альтернативы вы можете улучшить фиктивный объект, возвращаемый mock_open:

Python 3

class ReportMonitor(unittest.TestCase):
    def test_generate_cfg_thresh_map(self):
        m = mock_open(read_data='ENTRY_THRESH_COUNT 200')
        m.return_value.__iter__ = lambda self: self
        m.return_value.__next__ = lambda self: next(iter(self.readline, ''))
        with patch('app.open', m):
            app.generate_cfg_thresh_map()
            assert app.max_eval_count == 200

Python 2

class ReportMonitor(unittest.TestCase):
    def test_generate_cfg_thresh_map(self):
        m = mock_open(read_data='ENTRY_THRESH_COUNT 200')
        m.return_value.__iter__ = lambda self: iter(self.readline, '')
        with patch('app.open', m):
            app.generate_cfg_thresh_map()
            assert app.max_eval_count == 200

Кредиты: Настройка unittest.mock.mock_open для итерации .

...