【问题标题】:Mock method of an object inside function [python]函数内部对象的模拟方法[python]
【发布时间】:2020-10-27 12:11:27
【问题描述】:

我有两个文件:- file1.py 和 file2.py

file2.py 有以下代码:-

import json

def fun1():
    s = "{'function1': 'val1'}"
    s = json.dumps(s)
    print("in fun1 ", s)
    return s

def fun2():
    s = "{'function2': 'value2'}"
    s = json.dumps(s)
    print("in fun2 ", s)
    return s

def fun5():
    fun2()
    return fun1()

file1.py 有以下代码

from mockito import when, unstub
from file2 import fun5

def mock_the_function():
    when("file2.fun1.json").dumps(...).thenReturn("something something")
    print(fun5())
    unstub()

我只想在“fun1”中模拟“转储”,而不是“fun2”。我写的代码显示错误。我不想通过参数比较来做到这一点。有没有其他方法可以让函数在“何时”中传递?

【问题讨论】:

    标签: python json unit-testing mocking mockito


    【解决方案1】:

    首先简短说明:

    • json.dumps 接受一个对象,而不是字符串,因此在 fun1fun2 中调用它有点多余。也许您正在寻找json.loads

    接下来我会考虑一些不同的方法:

    • 当您模拟json.dumps 时,您想模拟file2 模块的json 属性,因此在您的测试设置代码中它只是 when("file2.json")...

    • 因为(如上),我们在 file2 模块中全局模拟 json 模块,所以不可能,如你所问,在单个测试的上下文中,在 @ 内部模拟 json.dumps 987654333@ 但不是fun2,但我建议简单地进行两个测试,然后unstub 采用拆卸方法。例如:

    from unittest import TestCase
    
    class TestExample(TestCase):
        def tearDown(self):
            unstub()
    
        def test_fun1(self):
            when("file2.json").dumps(...).thenReturn("something something")
            # in this invocation json is stubbed
            self.assertEqual(fun1(), "something something")
    
        def test_fun2(self):
            # but now unstub has been called so it won't be stubbed anymore.
            self.assertEqual(fun2(), "...output of fun2...")
    

    另一种选择是fun1fun2 采用一个函数来完成全局json 模块当前正在执行的工作。 Dependency Inversion Principle 的这种使用使代码更具可测试性,这意味着您甚至不需要在测试中使用 mockito。例如:

    def fun1(json_decoder):
       s = "..."
       return json_decoder(s)
    
    # ....
    from unittest.mock import MagicMock
    
    def test_fun_1():
       mock_decoder = MagicMock()
       mock_decoder.return_value = "asdf"
       assert fun1(mock_decoder) == "asdf"
    

    【讨论】:

    • 1.因为,python 中的一切都是对象。我认为字符串可以在转储中传递。但是,是的,这有点多余,TBH。我应该以负载而不是转储为例。 2. 那么,我所要求的不可能实现?我的意思是那东西是不可能的,对吧?
    • 如果我正确理解了您的问题,不,我不相信只能在 fun1 中模拟全局 json 模块而不是 fun2。但是,正如我在回答中提到的那样,还有其他方法可以编写 1)您的函数或 2)您的测试,允许您测试您想要在问题中测试的行为。
    猜你喜欢
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多