猴子补丁python与声明

时间:2015-06-18 10:50:58

标签: python pytest with-statement monkeypatching test-coverage

我正在使用py.test进行python单元测试。请考虑以下代码:

def mytest():
    "Test method"
    print "Before with statement"
    with TestClass('file.zip', 'r') as test_obj:
        print "This shouldn't print after patching."
        # some operation on object.
    print "After with statement."

是否可以将monkeypatch TestClass类设为with块中的代码变为noop

例如,修补后的输出应为:

Before with statement
After with statement

我知道我可以修补mytest函数本身,但这是为了获得更好的测试覆盖率。

我已经尝试了一些关于以下几行的内容但无法使其正常工作。

class MockTestClass(object):
    def __init__(self, *args):
        print "__init__ called."

    def __enter__(self):
        print "__enter__ called."
        raise TestException("Yeah done with it! Get lost now.")

    def __exit__(self, type, value, traceback):
        print "__exit__ called."

module_name.setattr('TestClass',  MockTestClass)

2 个答案:

答案 0 :(得分:1)

我认为您尝试做的事情是Python语言规范所禁止的。

正如您在PEP-343中所看到的"与"的定义声明不允许任何尝试提前退出上下文:

$.ajax({
    url: "url/to/your/api/that/returns/lat/long",
    success: function(result) {
        // process your JSON result and set the lat/long
    }
});

有人建议将此更改为您需要的功能(PEP-377),但这已被拒绝。

答案 1 :(得分:0)

从@ Peter的回答中可以清楚地看出,我们无法将整个区块设为noop。 我最后为我的用例做了以下。

# Module foo.py
class Foo(object):
    def __init__(self):
        print "class inited"

    def __enter__(self):
        print "entered class"
        return None

    def foo(self):
        raise Exception("Not implemented")

    def __exit__(self, type, value, traceback):
        print "exited class"
        return True

----------------------------
# Module FooTest
import foo

class FooTest(object):
    def __init__(self):
        print "class inited"

    def __enter__(self):
        print "entered class"
        return None

    def __exit__(self, type, value, traceback):
        print "exited class"
        return True

try:
    foo.Foo()
    print "It shouldn't print"
except:
    print "Expected exception"
setattr(foo, 'Foo', FooTest)
print "Patched"
with foo.Foo() as a:
    a.foo()
    print "It shouldn't print"
print 'Test passed!'