条件模拟:如果条件匹配,则调用原始函数 [英] Conditional mocking: Call original function if condition does match

查看:86
本文介绍了条件模拟:如果条件匹配,则调用原始函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在模拟中有条件地调用原始方法?

How can I conditionally call the orignal method in a mock?

在此示例中,如果bar=='x',我只想伪造一个返回值.否则,我想调用原始方法.

In this example I only want to fake a return value if bar=='x'. Otherwise I want to call the original method.

def mocked_some_method(bar):
    if bar=='x':
        return 'fake'
    return some_how_call_original_method(bar)

with mock.patch('mylib.foo.some_method', mocked_some_method):
    do_some_stuff()

我知道这有点奇怪.如果我想在侧面do_some_stuff()中伪造mylib.foo.some_method,那么它应该是无条件的.对some_method的所有(不是某些)调用都应该被模拟.

I know that it is a bit strange. If I want to fake mylib.foo.some_method in side do_some_stuff() it should be condition-less. All (not some) calls to some_method should be mocked.

在我的情况下,这是一个集成测试,而不是一个很小的单元测试,并且mylib.foo.some_method是一种经常使用的调度程序.在一种情况下,我需要伪造结果.

In my case it is an integration test, not a s tiny unittest and mylib.foo.some_method is a kind of dispatcher which gets used very often. And in one case I need to fake the result.

四年前我写了这个问题.今天,进行条件模拟感觉很奇怪. cks子只能在测试中使用.测试(和生产代码)应该简单而小巧.测试应该是无条件的.当我写这个问题时,我们仍然使用大量的生产方法和长期的测试.今天,我遵循这些规则(简单方法,无条件测试...).我写下了我的发现:我的编程指南

I wrote this question four years ago. Today, it feels very strange to do conditional mocking. Mocks should only get used in tests. Tests (and production code) should be simple and small. Tests should be conditionless. As I wrote this question, we still used huge production methods and long test. Today, I follow these rules (simple methods, conditionless tests ...). I wrote my findings down: my programming guidelines

推荐答案

如果只需要替换行为而不关心模拟的调用assert函数,则可以使用new参数;否则,您可以使用可调用的 side_effect .

If you need just replace behavior without care of mock's calls assert function you can use new argument; otherwise you can use side_effect that take a callable.

我猜想some_method是一个对象方法(而不是staticmethod),因此您需要引用它的对象来调用它.包装程序应将对象声明为第一个参数,并且您的补丁程序应使用autospec=Trueside_effect情况下使用正确的签名.

I guess that some_method is a object method (instead of a staticmethod) so you need a reference its object to call it. Your wrapper should declare as first argument the object and your patch use autospec=True to use the correct signature for side_effect case.

最后的技巧是保存原始方法引用,并使用它进行调用.

Final trick is save the original method reference and use it to make the call.

orig = mylib.foo.some_method
def mocked_some_method(self, bar):
    if bar=='x':
        return 'fake'
    return orig(self, bar)

#Just replace:
with mock.patch('mylib.foo.some_method', new=mocked_some_method):
    do_some_stuff()

#Replace by mock
with mock.patch('mylib.foo.some_method', side_effect=mocked_some_method, autospec=True) as mock_some_method:
    do_some_stuff()
    assert mock_some_method.called

这篇关于条件模拟:如果条件匹配,则调用原始函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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