Python如何重用Mock以避免多次编写Mock.patch?
给定如下代码:Python如何重用Mock以避免多次编写Mock.patch?,python,python-3.x,flask,mocking,python-mock,Python,Python 3.x,Flask,Mocking,Python Mock,给定如下代码: import flask import time app = flask.Flask(__name__) def authorize(): print('starting authorize io') time.sleep(1) print('done authorize io') class BlockingIo(): def __init__(self, n): self.n = n def do(self):
import flask
import time
app = flask.Flask(__name__)
def authorize():
print('starting authorize io')
time.sleep(1)
print('done authorize io')
class BlockingIo():
def __init__(self, n):
self.n = n
def do(self):
print('starting blocking io')
time.sleep(1)
print('ending blocking io')
@app.route('/', methods=['GET'])
@app.route('/<int:n>/', methods=['GET'])
def foo(n=1):
authorize()
b = BlockingIo(n)
b.do()
return str(n), 200
#app.run(port=5000)
m = mock.something('__main__.authorize')
m2 = mock.something('__main__.BlockingIo.do')
class TestBlockingIo(unittest.TestCase):
def test_1(self):
r = testapp.get('/1/')
self.assertEquals(r.data, b'1')
def test_2(self):
r = testapp.get('/2/')
self.assertEquals(r.data, b'2')
但是,我不想一遍又一遍地写出@mock.patch
decorator
我知道我们可以使用类装饰器,我可以使用子类来实现更高的可重用性:
@mock.patch('__main__.authorize')
@mock.patch('__main__.BlockingIo.do')
class TestBlockingIo(unittest.TestCase):
def test_1(self, m, m2):
r = testapp.get('/1/')
self.assertEquals(r.data, b'1')
def test_2(self, m, m2):
r = testapp.get('/2/')
self.assertEquals(r.data, b'2')
但是,这会强制类中的所有测试函数为每个模拟获取一个额外参数。如果此类中的测试不需要模拟阻塞IO
或授权
,该怎么办
我想我想要的是一种实现以下目标的方法:
import flask
import time
app = flask.Flask(__name__)
def authorize():
print('starting authorize io')
time.sleep(1)
print('done authorize io')
class BlockingIo():
def __init__(self, n):
self.n = n
def do(self):
print('starting blocking io')
time.sleep(1)
print('ending blocking io')
@app.route('/', methods=['GET'])
@app.route('/<int:n>/', methods=['GET'])
def foo(n=1):
authorize()
b = BlockingIo(n)
b.do()
return str(n), 200
#app.run(port=5000)
m = mock.something('__main__.authorize')
m2 = mock.something('__main__.BlockingIo.do')
class TestBlockingIo(unittest.TestCase):
def test_1(self):
r = testapp.get('/1/')
self.assertEquals(r.data, b'1')
def test_2(self):
r = testapp.get('/2/')
self.assertEquals(r.data, b'2')
如何重用我的@mock.patch(“\uu main\uuuuu.authorize”)
和@mock.patch(“\uu main\uuuuuu.BlockingIo.do”)
以避免重复测试?您可以在设置中使用并重用它们
补丁很好,因为当您完成测试时,您可以“取消补丁”,这意味着您不会像某些其他测试可能需要在实际代码上运行一样,永远让事情处于模拟状态
在上面的链接上,您将看到以下代码:
>>> class MyTest(TestCase):
... def setUp(self):
... patcher = patch('package.module.Class')
... self.MockClass = patcher.start()
... self.addCleanup(patcher.stop)
...
... def test_something(self):
... assert package.module.Class is self.MockClass
...
它工作得很好,但我并不喜欢为每个补丁调用patch()
、start()
和addCleanup()
您可以很容易地将其考虑到基类中,以便在测试类中重用:
class PatchMixin:
def patch(self, target, **kwargs):
p = mock.patch(target, **kwargs)
p.start()
self.addCleanup(p.stop)
class TestBlockingIo(unittest.TestCase, PatchMixin):
def setUp(self):
self.patch('__main__.authorize')
self.patch('__main__.BlockingIo.do')
def test_1(self):
r = testapp.get('/1/')
self.assertEquals(r.data, b'1')
def test_2(self):
r = testapp.get('/2/')
self.assertEquals(r.data, b'2')
如果您想在测试中配置模拟,请从补丁
存储并返回ps.start()
。