简体   繁体   English

为什么这个模拟脚本不起作用(unittest,Mocker,python)

[英]Why this mocking script doesn't work (unittest, Mocker, python)

I want to mock MyClass.toBeMockedMethod which is called in MyClass.mymethod using the following script. 我想模拟使用以下脚本在MyClass.mymethod中调用的MyClass.toBeMockedMethod。 It runs without actually mocking it. 它运行时并没有实际对其进行嘲笑。 Not sure why.... 不知道为什么。

class Test_mytest(MockerTestCase): 

   def mock_it_up(self, function, result=None, mmin=0, mmax=None):
      function = self.m.mock()
      function(ARGS)
      self.m.result(result)
      self.m.count(mmin, mmax)

   def setUp(self):
      self.m = Mocker()

      self.mock_it_up(MyClass.toBeMockedMethod)

      self.o=Myclass(0)


   def test_one_atom(self):
      self.o.mymethod()


   def tearDown(self):
      pass

if __name__ == '__main__': 
   main()

As with this question what you're really trying to do is patch your instance of MyClass . 就像这个问题一样 ,您真正想做的是修补 MyClass实例。 If MyClass is a new-style class then you can do this: 如果MyClass新样式的类,则可以执行以下操作:

class Test_mytest(MockerTestCase):

    def mock_it_up(self, function, result = None, mmin = 0, mmax = None):
        methodToMock = getattr(self.p, function)
        methodToMock()
        self.m.result(result)
        self.m.count(mmin, mmax)

    def setUp(self):
        self.m = Mocker()
        self.o = MyClass(0)
        self.p = self.m.patch(self.o)
        self.mock_it_up('toBeMockedMethod')
        # Put more calls to mock_it_up here.
        self.m.replay()

    def test_one_atom(self):
        self.o.mymethod()

This will modify self.o so that calls to toBeMockedMethod are mocked. 这将修改self.o以便对toBeMockedMethod调用进行toBeMockedMethod

However, if MyClass is not a new-style class then patching won't work. 但是,如果MyClass不是新型类,则修补将无法进行。 In this case, you can use type simulation to trick MyClass into doing what you want. 在这种情况下,您可以使用类型模拟来诱使MyClass进行所需的操作。 For example: 例如:

class Test_mytest(MockerTestCase):

    def mock_it_up(self, function, result = None, mmin = 0, mmax = None):
        methodToMock = getattr(self.mockObj, function)
        methodToMock()
        self.m.result(result)
        self.m.count(mmin, mmax)

    def setUp(self):
        self.m = Mocker()
        self.o = MyClass(0)
        self.mockObj = self.m.mock(MyClass)
        self.mock_it_up('toBeMockedMethod')
        # Put more calls to mock_it_up here.
        self.m.replay()

    def test_one_atom(self):
        MyClass.mymethod(self.mockObj)

Note that the mocker's mock method is called with the class to be type-simulated. 请注意,该mockmock方法与要进行类型模拟的类一起调用。 Later, instead of calling self.o.mymethod() we call MyClass.mymethod(...) . 后来,我们调用MyClass.mymethod(...)而不是调用self.o.mymethod() MyClass.mymethod(...) Now MyClass.mymethod() expects an instance of MyClass as its first argument, but fortunately the mock object is masquerading as an instance of MyClass so the call goes through. 现在, MyClass.mymethod()期望将MyClass的实例作为其第一个参数,但是幸运的是,模拟对象伪装成MyClass的实例,因此调用得以进行。 When mymethod() calls toBeMockedMethod() it will actually call the mocked method, not the real method. mymethod()调用toBeMockedMethod() ,它将实际上调用toBeMockedMethod()方法,而不是实际方法。

I quickly hacked up an test MyClass like this: 我迅速修改了一个测试MyClass如下所示:

class MyClass():
    def __init__(self, x):
        self.x = x

    def toBeMockedMethod(self):
        print "Not Mocked!"

    def mymethod(self):
        self.toBeMockedMethod()

and when I ran this code as a unit test I got: 当我将此代码作为单元测试运行时,我得到了:

.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK

which is the desired result. 这是理想的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM