pytest模拟本地对象实例在模拟对象中
问题
模拟并对无法从包含对象访问的本地实例对象进行断言。
最小示例
executor
是要模拟的类。
class Executor:
def execute(self, func, *args):
func(*args)
模拟executor
import pytest
@pytest.fixture
def executor(mocker):
mocker.patch('executor.Executor.execute')
return Executor()
testing executor.execute
立即调用。
def test_execute(executor):
func = lambda x: x**2
executor.execute(func, 7)
Executor.execute.assert_called_once_with(func, 7)
# this fails -- how to test a situation where one doesn't have access to the lambda
# func2 = lambda y:y**2
# Executor.execute.assert_called_once_with(func2, 7)
更普遍地
def test_execute_with_complex_args(executor):
def somefunc(x, y):
x.increment(y)
class SomeObj:
x=30
def increment(self, y):
self.x += y
obj = SomeObj()
executor.execute(somefunc, obj, 7)
Executor.execute.assert_called_once()
# this is assuming we have access to somefunc and obj instances
Executor.execute.assert_called_once_with(somefunc, obj, 7)
# how to verify that increment was called with arg 7?
# somefunc and obj are instances that are not accessible?
为什么这是重要的/对这种圆形测试的需求是什么?
我正在测试使用sqlalchemy
的数据库客户端。我想验证查询是通过正确参数执行的。客户端中的一个典型功能看起来像:
def get_job(self, job_id: UUID) -> Job:
return run_transaction(sessionmaker(bind=self.engine),
lambda s: copy(s.query(Job).filter(Job.id == job_id).one()))
sessionmaker
和run_transaction
是可模拟的,可以进行测试,但我想验证session.query
方法被适当地称为。
Problem
Mock and perform assertions on local instance objects that are not accessible from the encompassing object.
Minimum Example
Executor
is the class to be mocked.
class Executor:
def execute(self, func, *args):
func(*args)
Mocking Executor
import pytest
@pytest.fixture
def executor(mocker):
mocker.patch('executor.Executor.execute')
return Executor()
Testing Executor.execute
is called at once.
def test_execute(executor):
func = lambda x: x**2
executor.execute(func, 7)
Executor.execute.assert_called_once_with(func, 7)
# this fails -- how to test a situation where one doesn't have access to the lambda
# func2 = lambda y:y**2
# Executor.execute.assert_called_once_with(func2, 7)
More generally
def test_execute_with_complex_args(executor):
def somefunc(x, y):
x.increment(y)
class SomeObj:
x=30
def increment(self, y):
self.x += y
obj = SomeObj()
executor.execute(somefunc, obj, 7)
Executor.execute.assert_called_once()
# this is assuming we have access to somefunc and obj instances
Executor.execute.assert_called_once_with(somefunc, obj, 7)
# how to verify that increment was called with arg 7?
# somefunc and obj are instances that are not accessible?
Why is this important/what is the need for such a round-about testing?
I am testing a database client that uses SqlAlchemy
. I want to verify a query is executed with the right arguments. A typical function in the client looks like this:
def get_job(self, job_id: UUID) -> Job:
return run_transaction(sessionmaker(bind=self.engine),
lambda s: copy(s.query(Job).filter(Job.id == job_id).one()))
sessionmaker
and run_transaction
are mockable and can be tested but I want to verify the Session.query
method is called appropriately.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论