如何获得一个Mock对象的许多实例 [英] How to get many instances of one Mock object

查看:310
本文介绍了如何获得一个Mock对象的许多实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个受测系统B,该系统使用一些A,并且要模拟一些昂贵的功能,但B依赖于获取A的多个实例.

I have a System under test B that uses some A with some expensive function that I want to mock but B relies on getting multiple instances of A.

http://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch 说:如果该类被实例化多次,则可以使用side_effect每次返回一个新的模拟."但我不明白,:(

http://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch says: "If the class is instantiated multiple times you could use side_effect to return a new mock each time." but I don't understand, how :(

我将如何更改此示例:

import time

class A:
    def say_hi(self):
        print("lets do something horribly expensive")
        time.sleep(2)

class B:
    def __init__(self):
        self.a_map = {}
    def get_a(self):
        a = A()
        a.say_hi()
        self.a_map[a] = True

with patch('__main__.A') as mockA:
    b = B()
    def side_effect():
        # return DEFAULT  # no success
        return mockA  # no success neither
        # return mockA.clone()  # :(
    mockA.side_effect = side_effect  # no help
    # mockA.side_effect = [DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT]  # nope
    # mockA.side_effect = [mockA, mockA, mockA, mockA, mockA]  # nope
    # mockA.side_effect = [DEFAULT, mockA, mockA, mockA, mockA]  # nope, but hey! I get 2 instances in my key set now!
    # mockA.side_effect = [DEFAULT, mockA, mockA.clone(), mockA.clone().clone(), mockA.clone().clone().clone()]  # would work, but hey, seriously?

    for _ in range(5):
        b.get_a()
    print(b.a_map)
    assert len(b.a_map) == 5

产生以下输出:

{<MagicMock name='A' id='139998588645520'>: True}
Traceback (most recent call last):
  File "<stdin>", line 11, in <module>
AssertionError

(无需模拟,断言成功,但需要10秒钟.)

(Without mocking the assertion succeeds but it takes 10s.)

推荐答案

然后,您在嘲笑错误的内容.如果say_hi是您要模拟的昂贵部分,请模拟一下.这样您就不必再烦于side_effects了.

You're mocking the wrong thing then. If say_hi is the expensive portion you want to mock away, then mock that. Then you don't have to mess with side_effects.

with patch('__main__.A.say_hi'):
    b = B()
    for _ in range(5):
        b.get_a()
    print(b.a_map)
    assert len(b.a_map) == 5

要明确回答使用side_effects创建单独的模拟实例"的问题,可以将Mock指定为要返回的对象.

To explicitly answer your question of 'creating separate mock instances with side_effects', you would specify Mock as the object to be returned.

from mock import Mock
with patch('__main__.A') as mockA:
    b = B()
    mockA.side_effect = Mock
    for _ in range(5):
        b.get_a()
    print(b.a_map)
    assert len(b.a_map) == 5

这篇关于如何获得一个Mock对象的许多实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆