我有一个fixture,它在初始化gui.Buttons
期间创建mocker.Mock
而不是gui.Menu
对象。引用存储在Buttons.menu
属性中。在我的测试中,我检查是否在gui.Buttons.add
中调用了正确的函数。参数化测试运行良好,直到我满足了应该调用gui.Menu
方法的条件。现在有一个模拟
import pytest
from project import gui
@pytest.fixture
def buttons(mocker):
mocker.patch('project.gui.tk.Frame.__init__', return_value=None)
mocker.patch('project.gui.tk.Button')
return gui.Buttons(mocker.Mock())
@pytest.mark.parametrize('value,patched',(
(None, 'project.gui.show_no_connection'),
(False, 'project.gui.Buttons.process_data'),
(True, 'pytest.Mock.show_error'),
))
def test_add_calls_function(buttons, value, patched, mocker):
mocker.patch('project.gui.Buttons.exist_check', return_value=value)
mocked = mocker.patch(patched)
buttons.add()
mocked.assert_called_once()
使用real-object,我可以在@pytest.mark.parametrize
内写入(True, 'project.gui.Menu.show_error')
,而不是(True, 'pytest.Mock.show_error')
它不工作并生成ModuleNotFoundError: No module named 'pytest.Mock'
我想知道是否有可能在我的装置中patch
创建模拟对象,使其像其他参数化示例一样工作。有可能吗?如果我对它的理解是错误的,请纠正我
测试代码如下所示:
import tkinter as tk
import tkinter.messagebox as msg
from project.connection import Database
def show_no_connection():
msg.showerror('Error', 'Could not perform operation. Try again later.')
class Menu(tk.Tk):
def __init__(self):
super().__init__()
self.form = Form()
def show_error(self, message):
self.form.clear()
msg.showerror('Error', message)
class Form(tk.Frame):
def clear(self):
print('Clearing...')
def get(self):
return {'Title': 'Test', 'ISBN': 87327837823}
class Buttons(tk.Frame):
def __init__(self, menu):
super().__init__(menu)
self.menu = menu
def process_data(self, data, operation):
operation(data)
def add(self):
data = self.menu.form.get()
exists = self.exist_check(data.get('ISBN', None))
if exists is None:
show_no_connection()
else:
if exists:
self.menu.show_error(
'Record with set ISBN already exists in database.')
else:
self.process_data(data, Database().add)
@staticmethod
def exist_check(number):
if number:
return Database().search({'ISBN': number})
return False
显示错误:
=================================== FAILURES ===================================
_________ test_add_calls_function[True-project.gui.Gui.show_error] _________
buttons = <[AttributeError("'Buttons' object has no attribute '_w'") raised in repr()] Buttons object at 0x7f840114aa10>
value = True, patched = 'project.gui.Gui.show_error'
mocker = <pytest_mock.plugin.MockFixture object at 0x7f840114ab90>
@pytest.mark.parametrize('value,patched',(
(None, 'project.gui.show_no_connection'),
(False, 'project.gui.Buttons.process_data'),
(True, 'project.gui.Gui.show_error'),
))
def test_add_calls_function(buttons, value, patched, mocker):
mocker.patch('project.gui.Buttons.exist_check', return_value=value)
mocked = mocker.patch(patched)
buttons.add()
> mocked.assert_called_once()
E AssertionError: Expected 'show_error' to have been called once. Called 0 times.
tests/test_gui_buttons.py:88: AssertionError
我看不出有可能在同一个测试中处理这个问题-您可能需要为最后一个调用进行单独的测试。问题是菜单已经被模拟,您需要特定的菜单模拟来测试函数调用(函数将从该模拟实例调用)。
以下是一个可能的工作实现:
相关问题 更多 >
编程相关推荐