【问题标题】:Test A mock is being taken to Test B测试 A 模拟被带到测试 B
【发布时间】:2021-09-11 04:17:10
【问题描述】:

我在 Python 中有以下单元测试(使用 Python 3.8):

def test_Wrapper_permanent_cookie_OK_True(self):
    # Some stuff

    mock_3 = PermanentCookie
    mock_3.create_permanent_cookies_response = mock.Mock(return_value=response)

    # The following line uses this mock on its execution
    result = permanentcookies.Wrapper_permanent_cookie(Input)
    
    # Test passes (response gets defined previously)
    self.assertTrue(result == (response, None))

执行以下测试时问题开始。这是对我之前模拟的函数的测试。

def test_create_permanent_cookies_response(self):

     permanentcookies = PermanentCookie()
     result = permanentcookies.create_permanent_cookies_response(status2, error2)

     # Test does not pass because "result" is not the execution of the function but the mock from the previous test (response gets defined previously)
     self.assertTrue(result == response)

关于如何完全删除以前的模拟/将每个测试与其余测试隔离/...的任何建议?

提前致谢!

----------------------------------- --------编辑---------------------------------- ---

我的测试功能是使用补丁方法。但是在这些补丁中,有一个类是我需要测试功能的。也许我缺少一些关于修补类的基本知识......我的代码:


    @mock.patch('src.servicios.permanent_cookies.PermanentCookie')
    @mock.patch('src.servicios.permanent_cookies.utilities.get_current_datetime')
    @mock.patch('src.servicios.permanent_cookies.queries.query_permanent_cookie')
    def test_Wrapper_permanent_cookie_OK_True(self, mock_1, mock_2, mock_3):

         # The following line is not sending my return_value expectation to function usage
         mock_3.create_permanent_cookies_response.return_value = 'test'


        # This is the usage of the class I mocked on the patch above
        permanentcookies = PermanentCookie()
        # Unexpected outcome as the method I passed the return_value method did not return that value.
        result = permanentcookies.Wrapper_permanent_cookie(Input)

【问题讨论】:

    标签: python unit-testing mocking python-unittest patch


    【解决方案1】:

    似乎在类中修补函数的方法是首先给出类,然后在补丁装饰器上给出函数。只要补丁在装饰器上(而不是像 mock.Mock(return_value=...) 那样在测试中),补丁就在类的函数级别上正确完成,并且不会比这个测试进一步扩展。

    对于所有到达这一点的人,从编辑中,答案是:

    @mock.patch('src.servicios.permanent_cookies.PermanentCookie.create_permanent_cookies_response')
    @mock.patch('src.servicios.permanent_cookies.utilities.get_current_datetime')
    @mock.patch('src.servicios.permanent_cookies.queries.query_permanent_cookie')
    def test_Wrapper_permanent_cookie_OK_True(self, mock_1, mock_2, mock_3):
    
        mock_3.return_value = 'Your Value'
    
        permanentcookies = PermanentCookie()
        # Now getting the correct 
        result = permanentcookies.Wrapper_permanent_cookie(Input)
    

    【讨论】:

      【解决方案2】:

      通常,补丁不应超出其当前上下文。

      所以测试 1 中的所有内容都已修补:

      @patch(...func1)
      def test_test1(sef):
          func1() # <- patched.
      

      当你来测试 2 时将被重置:

      def test_test2(sef):
          func1() # <- not patched.
      

      但有时,您确实需要将未打补丁的函数版本与打补丁的版本一起保留:

      在这种情况下,您可以这样做:

      _unpatched = func1
      
      @patch(...func1)
      def test_patched_with_unpatched(self):
          func1()      # <- patched.
          _unpatched() # <- func1 not patched.
      

      【讨论】:

      • 非常感谢@Florian Fasmeyer!看来问题和你描述的一样。只是稍微修改了一下那条线,它就起作用了。再次非常感谢! :)
      【解决方案3】:

      您实际上并没有在任何地方使用patch。它使用了在测试结束时删除模拟的补丁。

      patch() 充当函数装饰器、类装饰器或上下文管理器。在函数体或 with 语句中,target 被一个 new 对象修补。 当函数/with语句退出时,补丁被撤消。

      【讨论】:

      • 那你会如何使用补丁呢?内联代码将不胜感激
      • 链接的文档显示了如何使用它,以及代码示例。你自己试过了吗?有什么问题吗?
      • 是的,我在问题上添加了编辑部分。问题是这个补丁没有像我预期的那样运行......
      • 非常感谢,@win!看来问题和你描述的一样。只是稍微修改了一下那条线,它就起作用了。再次非常感谢! :)
      猜你喜欢
      • 1970-01-01
      • 2023-03-09
      • 2014-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多