【问题标题】:Mock an attribute in python class for unit testing模拟python类中的属性以进行单元测试
【发布时间】:2016-10-26 23:07:54
【问题描述】:

我想在我的单元测试中模拟self.var,因为名称服务器查找失败。我已经使用patch 尝试了很多东西,但我无法让它工作。模拟self.var 的最佳方式是什么?

我的班级定义如下:

class A:
   def __init__(self):
       self.var = Pyro4.Proxy(self.ns.lookup(temp_name))
   def method_1(self):
   .....

我的单元测试是这样的:

class TestA(TestCase):
    def setUp(self):
        self.temp_A = classA()    
    def test_method(self):
       self.temp_A.method_1()`

【问题讨论】:

    标签: python unit-testing nose python-unittest python-unittest.mock


    【解决方案1】:

    你可以在这里做两件事,最简单的只是修补 Pyro4.Proxy,像这样:

    from unittest.mock import patch
    # or from mock import create_autospec if you are in py2
    
    class TestA(TestCase):
      @patch('Pyro4.Proxy', autospec=True)
      def test_method(self):
         temp_A = A()
         temp_A.method_1()
    

    诀窍是修补“正确的对象”并且在你修补之后(在你的测试函数中)之前不要实例化类,Pyro4.Proxy 是我可以从你的代码中推断出的最好的对象,但是如果你的 @987654323 @ 在 my_module 中,也许最好的补丁对象是 my_module.Pyro4.Proxy

    您可能想要的另一件事是模拟 var 变量。然后当您在 __init__ 方法中定义 self.var 并假设您不想模拟整个 __init__ 方法时,您可以

    from unittest.mock import create_autospec
    # or from mock import create_autospec if you are in py2
    
    class TestA(TestCase):
      def setUp(self):
         self.temp_A = classA()
         self.temp_A.var = create_autospec(Pyro4.Proxy)(None)
    
      def test_method(self):
         self.temp_A.method_1()
    

    如果你可以稍微重构你的类,我建议将 var 设置为一个易于模拟的属性

    class A(object):
       def __init__(self):
             ...
       @property
       def var(self):
           return Pyro4.Proxy(self.ns.lookup(temp_name))
    
       def method_1(self):
           .....
    

    然后你的测试类可以是

    from unittest.mock import create_autospec, PropertyMock
    class TestA(TestCase):
      def setUp(self):
         self.temp_A = classA()
         type(self.temp_A).var = PropertyMock(side_effect=lambda *x, **y: create_autospec(Pyro4.Proxy)(*x, **y))
    
      def test_method(self):
         self.temp_A.method_1()
    

    【讨论】:

      【解决方案2】:

      我认为处理这个问题的最简单方法是剔除被测类。

      在测试文件中

      class AStub(A):
         def __init__(self):
           #  By pass super constructor
           self.var = None
      
      class TestA(TestCase):
        def setUp(self):
          self.helper = AStub()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-15
        • 2015-07-01
        • 1970-01-01
        • 2020-04-06
        • 1970-01-01
        • 1970-01-01
        • 2017-03-13
        • 2013-03-25
        相关资源
        最近更新 更多