如何使用 pytest-mock 模拟 class 并控制 py.test 中的返回值?
How do I mock a class and control a returned value in py.test with pytest-mock?
我正在尝试使用 py.test
来测试一些执行各种 LDAP
搜索和修改的代码。
我正在使用 pytest-mock
,但我无法理解如何模拟 LDAP 对象的创建,以及如何在 search_s()
时控制它 returns在模拟对象上调用。
我以为这会做我想做的事,但测试失败,计数显示生成器函数 find_users()
永远不会产生任何结果。
import pytest
# Here is some code to simply test mocking out ldap.initialize(), and
# controlling the return value from calls to search_s()
import ldap
def find_users(ldap_url, admin_user, admin_password, userbase):
lobj = ldap.initialize(ldap_url)
lobj.simple_bind_s(admin_user, admin_password)
for i in lobj.search_s(userbase, ldap.SCOPE_SUBTREE, '*'):
yield i[1]['uid'][0]
class TestMocking:
@pytest.fixture()
def no_ldap(self, mocker):
return mocker.patch('ldap.initialize')
def test_ad_one_user(self, no_ldap):
# try and modify how search_s() would return
no_ldap.search_s.return_value = ('', {'uid': ['happy times']})
count = 0
for i in find_users('', '', '', ''):
count += 1
assert i=='happy times'
assert count == 1
我认为您可能对 https://docs.python.org/3/library/unittest.mock.html 和 pytest 猴子补丁感到困惑。我不认为两者的行为方式相同。
您可以使用模拟补丁使其工作
(https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch)
@pytest.fixture()
def no_ldap(self):
patcher = mock.patch('ldap.initialize')
patcher.start()
yield patcher
patcher.stop()
你可以直接使用补丁(你的结构有些问题):
from mock import patch, Mock
import pytest
# Here is some code to simply test mocking out ldap.initialize(), and
# controlling the return value from calls to search_s()
import ldap
def find_users(ldap_url, admin_user, admin_password, userbase):
lobj = ldap.initialize(ldap_url)
lobj.simple_bind_s(admin_user, admin_password)
for i in lobj.search_s(userbase, ldap.SCOPE_SUBTREE, '*'):
yield i[1]['uid'][0]
class TestMocking:
@patch('ldap.initialize')
def test_ad_one_user(self, no_ldap):
# try and modify how search_s() would return
data = [('', {'uid': ['happy times']})]
search_s = Mock(return_value=data)
no_ldap.return_value = Mock(search_s=search_s)
count = 0
for i in find_users('', '', '', ''):
count += 1
assert i=='happy times'
assert count == 1
我正在尝试使用 py.test
来测试一些执行各种 LDAP
搜索和修改的代码。
我正在使用 pytest-mock
,但我无法理解如何模拟 LDAP 对象的创建,以及如何在 search_s()
时控制它 returns在模拟对象上调用。
我以为这会做我想做的事,但测试失败,计数显示生成器函数 find_users()
永远不会产生任何结果。
import pytest
# Here is some code to simply test mocking out ldap.initialize(), and
# controlling the return value from calls to search_s()
import ldap
def find_users(ldap_url, admin_user, admin_password, userbase):
lobj = ldap.initialize(ldap_url)
lobj.simple_bind_s(admin_user, admin_password)
for i in lobj.search_s(userbase, ldap.SCOPE_SUBTREE, '*'):
yield i[1]['uid'][0]
class TestMocking:
@pytest.fixture()
def no_ldap(self, mocker):
return mocker.patch('ldap.initialize')
def test_ad_one_user(self, no_ldap):
# try and modify how search_s() would return
no_ldap.search_s.return_value = ('', {'uid': ['happy times']})
count = 0
for i in find_users('', '', '', ''):
count += 1
assert i=='happy times'
assert count == 1
我认为您可能对 https://docs.python.org/3/library/unittest.mock.html 和 pytest 猴子补丁感到困惑。我不认为两者的行为方式相同。
您可以使用模拟补丁使其工作 (https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch)
@pytest.fixture()
def no_ldap(self):
patcher = mock.patch('ldap.initialize')
patcher.start()
yield patcher
patcher.stop()
你可以直接使用补丁(你的结构有些问题):
from mock import patch, Mock
import pytest
# Here is some code to simply test mocking out ldap.initialize(), and
# controlling the return value from calls to search_s()
import ldap
def find_users(ldap_url, admin_user, admin_password, userbase):
lobj = ldap.initialize(ldap_url)
lobj.simple_bind_s(admin_user, admin_password)
for i in lobj.search_s(userbase, ldap.SCOPE_SUBTREE, '*'):
yield i[1]['uid'][0]
class TestMocking:
@patch('ldap.initialize')
def test_ad_one_user(self, no_ldap):
# try and modify how search_s() would return
data = [('', {'uid': ['happy times']})]
search_s = Mock(return_value=data)
no_ldap.return_value = Mock(search_s=search_s)
count = 0
for i in find_users('', '', '', ''):
count += 1
assert i=='happy times'
assert count == 1