Python模拟Elasticsearch连接生成器`with`语句

时间:2018-11-15 09:32:32

标签: python python-2.7 mocking with-statement python-mock

我想用一个带有with语句的函数来测试一个类:

func_to_test():
   ....
   with self.__elastic_generator.get() as es:
      print 'about to use the es connection....'

所以我模拟了elstic_generator,并在创建测试的类时模拟了get函数:

elastic_gen = mock.Mock()
elstic_gen.get = mock.Mock()
elastic_gen.get.side_effect = ['mocked elastic connection']
tested_class = TestedClass(elastic_gen)
tested_class.func_to_test()

但是由于某些原因,在使用with语句时不起作用。 但是,如果在不使用with的情况下获得连接,则如下所示:

x = self.__elastic_generator.get()

然后运行正常,我得到x = 'mocked elastic connection'

所以我想这个问题与使用with时进行的更多函数调用有关,并且我没有嘲笑这些函数。

有人可以解释一下幕后发生的事情吗?我还能嘲笑什么,以便能够使用with语句进行测试?

谢谢。

1 个答案:

答案 0 :(得分:1)

with语句是一个称为上下文管理器的概念。当您输入__enter__时,上下文管理器具有with函数;当您退出__exit__时,上下文管理器具有with函数(通过抬高或在区块内完成执行。

__enter__函数应返回您希望在as之后分配给变量的任何值,在这种情况下为es。因此,要对此进行模拟,您不想模拟.get()的返回值,而是希望模拟.get().__enter__()的返回值。看起来应该像这样:

elastic_gen = mock.Mock()
elastic_gen.return_value.__enter__.return_value = 'mocked elastic connection'