为什么python模拟补丁不起作用? [英] Why python mock patch doesn't work?

查看:77
本文介绍了为什么python模拟补丁不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个文件

spike.py

class T1(object):
    def foo(self, afd):
        return "foo"

    def get_foo(self):
        return self.foo(1)


def bar():
    return "bar"

test_spike.py:

test_spike.py:

from unittest import TestCase
import unittest
from mock import patch, MagicMock
from spike import T1, bar


class TestStuff(TestCase):
    @patch('spike.T1.foo', MagicMock(return_value='patched'))
    def test_foo(self):
        foo = T1().get_foo()
        self.assertEqual('patched', foo)

    @patch('spike.bar')
    def test_bar(self, mock_obj):
        mock_obj.return_value = 'patched'
        bar = bar()
        self.assertEqual('patched', bar)


if __name__ == "__main__":
    unittest.main()

当我运行python test_spike.py时,第一个测试用例将通过,但第二个将失败. 而我改用nosetests test_spike.py,那么两个都失败了.

When I run python test_spike.py, the first test case would pass, but the second would fail. and I switch to use nosetests test_spike.py, then both two are failed.

我不明白这是怎么发生的?这些情况本应全部通过.

I don't understand how this happened? These cases supposed to pass all.

推荐答案

对于 test_foo ,您没有正确使用补丁.您应该像这样使用它:

For test_foo you are not using patch correctly. You should be using it like this:

class TestFoo(TestCase):
@patch.object(T1, 'foo', MagicMock(return_value='patched'))
def test_foo(self):
    foo = T1().get_foo()
    self.assertEqual('patched', foo)

这给了我

nosetests test_spike.py 
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

现在,第二个示例不起作用,因为您导入了bar函数(获取对其的引用),然后尝试对其进行模拟.模拟某些内容时,您无法更改变量的内容(对原始函数的引用).要解决这个问题,您应该使用@falsetru建议的方法,例如:

Now the second example does not work because you import bar function (get a reference to it) and then try to mock it. When you mock something you can't change what your variables hold (reference to original function). To fix this you should use @falsetru suggested method like:

from unittest import TestCase
import unittest
from mock import patch
import spike


class TestFoo(TestCase):
    @patch('spike.bar')
    def test_bar(self, mock_obj):
        mock_obj.return_value = 'patched'
        value = spike.bar()
        self.assertEqual('patched', value)


if __name__ == "__main__":
    unittest.main()

这给了我

python test_spike.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

但是当我尝试用鼻子跑它时,我得到了:

But when I try to run it with nose I get:

 nosetests test_spike.py
F
======================================================================
FAIL: test_bar (src.test_spike.TestFoo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/zilva/envs/test/local/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
    return func(*args, **keywargs)
  File "/home/zilva/git/test/src/test_spike.py", line 11, in test_bar
    self.assertEqual('patched', value)
AssertionError: 'patched' != 'bar'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

发生这种情况是因为我在不正确的地方打补丁.我的目录结构是:

This happends because I am patching not in the right place. My directory structure is:

test/
└── src/
    ├── spike.py
    ├── test_spike.py
    └── __init__.py

并且我从src目录运行测试,因此我应该使用项目根目录中的路径进行修补,例如:

and I run tests from src directory so I should be patching using path from project root directory like:

@patch('src.spike.bar')

这会给我:

nosetests test_spike.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

或者如果我在测试目录中:

or if I am at test directory:

nosetests src/test_spike.py
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

这篇关于为什么python模拟补丁不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆