我正在使用FileField为Django模型编写测试用例。我想更改上传路径,以防止测试对系统的其余部分产生副作用。
我尝试将可调用对象传递给upload_to并在测试中对其进行修补:
#models.py
upload_path = lambda x, y: 'files'
class Model(models.Model):
file = models.FileField(upload_to=upload_path)
#tests.py
test_path = mock.Mock()
test_path.return_value = 'files/test'
@mock.patch('models.upload_path', new=test_path)
class ModelTest(object):
...
Run Code Online (Sandbox Code Playgroud)
但是,这似乎不起作用,我相信原因是在运行任何测试代码之前FileField取消了upload_path的引用,因此现在修补补丁太晚了。
如何让测试代码更改“ upload_to”是什么?失败了,模型如何检查是否正在通过测试运行?
当使用该mock库编写Python测试时,我经常会收到“用什么方法调用参数”,
from __future__ import print_function
import mock
m = mock.MagicMock(side_effect=lambda x: x * x)
m(4)
print("m called with: ", m.call_args_list)
Run Code Online (Sandbox Code Playgroud)
(这将打印m called with: [call(4)])。问题:有什么方法可以获取返回值(在这种情况下为16)?
详细信息:在我的特定情况下,我想使用side_effect返回一个子模拟对象:对该对象进行内部检查以查看其上的内容很重要。例如,“真实代码”(非测试代码)可能会写成,
myobj = m(4)
myobj.foo()
Run Code Online (Sandbox Code Playgroud)
使用side_effect似乎是一种方便的方法来返回新的子模拟对象,但也可以保持存在call_args_list。但是,似乎并没有MagicMock从side_effect函数中存储返回值……我错了吗?
例如:
import mock
class MyClass(object):
def foo(self, x, y, z):
return (x, y, z)
class TestMyClass(TestCase)
@mock.patch('MyClass')
def TestMyClass(self, MyClassMock):
foo_mock = MyClassMock.foo()
self.assertEquals((x, y, z), foo_mock)
Run Code Online (Sandbox Code Playgroud)
所以,真正的问题是:如何获得返回的测试内容得到这个<MagicMock name='MyClass.foo()' id='191728464'>或如何处理这个MagicMock对象来获得该测试的返回,该测试应该是一个包含3个元素的元组,而不是更多或更少?
任何建议,任何想法,任何论点都将受到欢迎.提前致谢!
使用模拟返回值修补Celery任务调用将返回<Mock name='mock().get()' ...>而不是预期return_value定义的mock_task.get.return_value = "value".但是,模拟任务在我的单元测试中正常运行.
这是我修补Celery任务的单元测试:
def test_foo(self):
mock_task = Mock()
mock_task.get = Mock(return_value={'success': True})
print mock_task.get() # outputs {'success': True}
with patch('app.tasks.my_task.delay', new=mock_task) as mocked_task:
foo() # this calls the mocked task with an argument, 'input from foo'
mock_tasked.assert_called_with('input from foo') # works
Run Code Online (Sandbox Code Playgroud)
以下是正在测试的功能:
def foo():
print tasks.my_task.delay # shows a Mock object, as expected
# now let's call get() on the mocked task:
task_result = tasks.my_task.delay('input from foo').get()
print task_result # => …Run Code Online (Sandbox Code Playgroud) 在 python 中是否有任何等效的严格模拟?一些机制来报告模拟方法的意外调用(在这个例子中是 action.step2()),就像在 GoogleMock 框架中一样。
class Action:
def step1(self, arg):
return False
def step2(self, arg):
return False
def algorithm(action):
action.step1('111')
action.step2('222')
return True
class TestAlgorithm(unittest.TestCase):
def test_algorithm(self):
actionMock = mock.create_autospec(Action)
self.assertTrue(algorithm(actionMock))
actionMock.step1.assert_called_once_with('111')
Run Code Online (Sandbox Code Playgroud) 我有一个具有昂贵__init__功能的类。我不希望从测试中调用这个函数。
出于本示例的目的,我创建了一个在__init__以下位置引发异常的类:
class ClassWithComplexInit(object):
def __init__(self):
raise Exception("COMPLEX!")
def get_value(self):
return 'My value'
Run Code Online (Sandbox Code Playgroud)
我有第二个类,它构造一个实例ClassWithComplexInit并使用它的函数。
class SystemUnderTest(object):
def my_func(self):
foo = ClassWithComplexInit()
return foo.get_value()
Run Code Online (Sandbox Code Playgroud)
我正在尝试围绕SystemUnderTest#my_func(). 我遇到的问题是无论我如何尝试模拟ClassWithComplexInit,该__init__函数总是被执行并引发异常。
class TestCaseWithoutSetUp(unittest.TestCase):
@mock.patch('mypackage.ClassWithComplexInit.get_value', return_value='test value')
def test_with_patched_function(self, mockFunction):
sut = SystemUnderTest()
result = sut.my_func() # fails, executes ClassWithComplexInit.__init__()
self.assertEqual('test value', result)
@mock.patch('mypackage.ClassWithComplexInit')
def test_with_patched_class(self, mockClass):
mockClass.get_value.return_value = 'test value'
sut = SystemUnderTest()
result = sut.my_func() # seems to not execute ClassWithComplexInit.__init__()
self.assertEqual('test value', …Run Code Online (Sandbox Code Playgroud) 是否可以模拟在函数内部导入的模块?
例如
def my_func(input):
import something_else
something_else.do_something(input)
Run Code Online (Sandbox Code Playgroud)
由于循环依赖,我在函数内部有一个导入。基于我的谷歌搜索,我认为我是 SOL,但想知道是否有人知道如何使这成为可能。
我只想验证 do_something 是否被调用。
我正在使用sqlalchemy查询数据库中的项目。并行地说,我是单元测试的新手,我正在尝试学习如何进行单元测试来测试数据库。我尝试使用模拟库进行测试,但到目前为止,这似乎非常困难。
因此,我编写了一段创建Session对象的代码。该对象用于连接数据库。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.exc import OperationalError, ArgumentError
test_db_string = 'postgresql+psycopg2://testdb:hello@localhost/' \
'test_databasetable'
def get_session(database_connection_string):
try:
Base = declarative_base()
engine = create_engine(database_connection_string)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
connection = session.connection()
return session
except OperationalError:
return None
except ArgumentError:
return None
Run Code Online (Sandbox Code Playgroud)
因此,我为此功能制作了一个单元测试用例:
import mock
import unittest
from mock import sentinel
import get_session
class TestUtilMock(unittest.TestCase):
@mock.patch('app.Utilities.util.create_engine') # mention the whole path
@mock.patch('app.Utilities.util.sessionmaker')
@mock.patch('app.Utilities.util.declarative_base')
def test_get_session1(self, …Run Code Online (Sandbox Code Playgroud) 我想模拟一个用于初始化类级(非实例)属性的模块级函数.这是一个简化的例子:
# a.py
def fn():
return 'asdf'
class C:
cls_var = fn()
Run Code Online (Sandbox Code Playgroud)
这是一个试图模拟a.fn()的单元测试:
# test_a.py
import unittest, mock
import a
class TestStuff(unittest.TestCase):
# we want to mock a.fn so that the class variable
# C.cls_var gets assigned the output of our mock
@mock.patch('a.fn', return_value='1234')
def test_mock_fn(self, mocked_fn):
print mocked_fn(), " -- as expected, prints '1234'"
self.assertEqual('1234', a.C.cls_var) # fails! C.cls_var is 'asdf'
Run Code Online (Sandbox Code Playgroud)
我相信问题是在哪里修补,但我已尝试导入两个变种没有运气.我甚至尝试将import语句移动到test_mock_fn()中,以便在aC进入作用域之前,模拟的a.fn()将"存在" - nope仍然失败.
任何见解将不胜感激!
例如,我有一些尝试访问列表的代码:
def some_code():
script_dir = os.path.dirname(sys.argv[0])
Run Code Online (Sandbox Code Playgroud)
我需要嘲笑sys.argv[0]。因此,我添加@patch.object到测试中:
import os
import sys
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
@mock.patch.object(sys, 'argv', mock.Mock(return_value=[THIS_DIR]))
def test_mytest():
some_code()
Run Code Online (Sandbox Code Playgroud)
但这是行不通的。Pytest引发错误:
> script_dir = os.path.dirname(sys.argv[0])
E TypeError: 'Mock' object does not support indexing
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
python-mock ×10
python ×9
mocking ×8
unit-testing ×6
celery ×1
celery-task ×1
django ×1
nosetests ×1
pytest ×1
python-2.7 ×1
sqlalchemy ×1
testing ×1