为什么在Python中修补和断言需要“自我”?

时间:2016-06-28 04:02:19

标签: python unit-testing mocking patch assert

我通常使用:

def create_patch(self, name, value = None):
    patcher = patch(name)
    mock = patcher.start()
    mock.return_value = value
    self.addCleanup(patcher.stop)
    return mock

def assertXmlEqual(self, a, b):
    with open(a, 'r') as f:
        axml = f.read()
    with open(b, 'r') as f:
        bxml = f.read()
    self.assertEqual(loads(dumps((parse(axml)))), loads(dumps((parse(bxml)))))

在测试用例中:

mockobj = self.create_patch('mymodule.myclass.mymethod', 'myvalue')

self.assertXmlEqual('expect.xml', 'result.xml')

但是对于每个单元测试类,我都要复制它。

有没有办法让这些更独立于测试用例,更像是lib,如.net中的MoqAssert以及Ruby中的mockexpect

以下是他们的行为方式。看到?它们独立于测试用例。

MoqAssert

var obj = new Moq.Mock<MyPackage.MyClass>() { CallBase = true };
obj.Setup(p => p.MyMethod(Moq.It.IsAny<string>())).Returns(false);

Assert.AreEqual(expect, result)

allowexpect

obj = double
allow(obj).to receive(:my_method).and_return('myvalue')

expect(result).to eq(expect)
expect(obj).to have_received(:my_method).exactly(3).times

1 个答案:

答案 0 :(得分:2)

您可以创建一个基本测试用例,然后让所有其他测试用例继承自 而不是unittest.TestCase

class MyBaseTestCase(unittest.TestCase):
    def create_patch(self, name, value = None):
        patcher = patch(name)
        mock = patcher.start()
        mock.return_value = value
        self.addCleanup(patcher.stop)
        return mock

    def assertXmlEqual(self, a, b):
        with open(a, 'r') as f:
            axml = f.read()
        with open(b, 'r') as f:
            bxml = f.read()
        self.assertEqual(loads(dumps((parse(axml)))), loads(dumps((parse(bxml)))))


class MyTestCaseThatTestsSomething(MyBaseTestCase):
    def test_something(self):
        self.patch('something.dependency', 'Hello World')
        result_xml = something()
        self.assertXmlEqual(result_xml, expected_xml)