在python类中模拟一个属性进行单元测试

时间:2016-10-26 23:07:55

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

我想在单元测试中模拟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()`

2 个答案:

答案 0 :(得分: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是我可以从您的代码中推断出的最佳对象,但如果你的class A位于my_module中,也许补丁的最佳对象是my_module.Pyro4.Proxy

你可能想要的另一件事就是模拟var变量。然后当您在self.var方法中定义__init__并假设您不想模拟整个__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()

答案 1 :(得分:0)

我认为解决这个问题的最简单方法就是将课程进行限制。

在测试文件

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

class TestA(TestCase):
  def setUp(self):
    self.helper = AStub()