(Python 3.4.0)

我收到了一个奇怪的错误,这花了我一段时间才能调试:



user.py

class User:

    def __init__(self, name):
        self.name = name


def new_user(name):
    user = User(name)




test.py

import unittest
from unittest.mock import Mock, patch

from user import new_user

@patch('user.User')
class TestUser(unittest.TestCase):

    @unittest.skip
    def test_new_user(self, mockUser):
        new_user('Frank')
        mockUser.assert_called_once_with('Frank')


unittest.main()




运行它将崩溃:

» python test.py
E
======================================================================
ERROR: test_new_user (__main__.TestUser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/mock.py", line 1125, in patched
    return func(*args, **keywargs)
TypeError: decorator() takes 1 positional argument but 2 were given

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

FAILED (errors=1)


删除跳过将使其正常运行。看来patchskip不能很好地堆叠。这是正确的,还是我在做愚蠢的事情?

最佳答案

unittest.skip需要自己的字符串参数,这是跳过测试的原因。

@unittest.skip("Not yet ready to test")
def test_new_user(self, mockUser):
    new_user('Frank')
    mockUser.assert_called_once_with('Frank')


您看到的交互来自skip装饰器,该方法本身将方法本身用作reason参数(def skip(reason):),这导致test_new_user绑定到装饰器中定义的一个单参数函数,而不是两个您在测试用例中定义的-argument函数。

请注意,如果您保留对skip的调用并注释掉patch,尽管test_new_user似乎没有收到其mockUser参数,您的测试仍会通过。



从技术上讲,unittest.skip本身不是装饰器;它是一个返回装饰器的函数,然后将其应用于test_new_user。使用常规的函数调用语法,您的代码可以

def test_new_user(self, mockUser):
    ...
test_new_user = unittest.skip(test_new_user)


当你需要的是

test_new_user = unittest.skip("my reason")(test_new_user)


您的test_new_user被绑定到装饰器本身,而不是装饰的方法。

关于python - mock.patch和unittest.skip之间的冲突,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32117409/

10-11 08:06