• py3相对import和mock的问题之二


    〇、前言

      本文主要用于记录问题,很难解决您的实际问题,见谅!

      主要介绍博主在mock的时候,一些写法问题导致的bug。技术有限,如果理解错了,欢迎留言,我会及时修改。

      本文问题核心:在python3 相对路径import的情况下,mock对应的模块,导致对应模块内其他模块导入错误。

    一、问题描述

    测试用例结构:

    a.py:

    # -*- coding: utf-8 -*-
    
    import jiliguala
    
    def afunc():
        print("this func a")

    b.py:

    # -*- coding: utf-8 -*-
    
    from . import a
    def bfunc():
        a.afunc()
        print("this func b")

    core.py:

    # -*- coding: utf-8 -*-
    
    import unittest
    import unittest.mock as mock
    
    def test_post(x):
        print("do test http: ", x)
    
    @mock.patch.dict("sys.modules", {
        "test.a": mock.Mock(),
    })
    class TestCore(unittest.TestCase):
        @mock.patch("a.afunc")
        def test1(self, test_post):
            import test.b as b
            b.bfunc()
            test_post.side_effect = test_post
            b.bfunc()
    
        @mock.patch("c.cpost")
        def test2(self, test_post):
            import test.c as c
            c.cfunc()
            test_post.side_effect = test_post
            c.cHttp()

      简单介绍一下,a文件是非py服务(用了一些莫名其妙的模块),b依赖于a,因此我在测试b中的代码需要将a进行隔离。

      在core代码中用装饰器的方式,将a模块隔离(from . import a这种写法,在sys.modules中就是test.a的形式),然后重写a.afunc的代码。

      好,看代码逻辑,貌似没什么问题。

    结果:

       我把整个a模块都mock了,怎么还会导入a里面的模块?

      写一个空的测试类,看看有没有mock

    结果:

      成功mock进去了……

      问题猜测:估计是我神奇的写法有问题。

      没错!如果直接mock那个神奇的模块的话,一点问题没有,但是如果确实有这么一个模块,用到了很多其他py命令行无法调用的模块的话,还是这种写法更好一点。

    二、问题的根本原因

      这种写法的原理是在sys.modules中加入Mock实例,使得和原来的模块隔离的。

      而python的import有个问题:

        from a import  b。用这个写法的话,会先初始化模块a,然后在a模块中初始化模块b。

    测试代码:

    from test import d
    import sys
    import test
    
    print(sys.modules)
    print(dir(test))

    结果:

      如图,发生问题的逻辑是:from import的时候,系统环境有对应路径,再import test的时候,会对其中的d进行初始化,导致d里面的东西也会跟着初始化。

      所以发生了上面这一幕,我明明把d都给mock了,但是d里面的import还是被执行了。

    三、解决方法

      对于这种方式,解决方法就是不用from import 或者 直接mock那个奇怪的模块。

      主要还是这种写法的问题

    四、总结

      还是直接mock不用的模块比较好,这方面需要注意写法。

      这篇文章在我眼里是不合格的文章,因为博主也看不懂,而且各种问题也没表述清楚……就当做是问题记录吧

  • 相关阅读:
    mmap 函数
    poisx 文件锁
    三次握手的第三个ACK包丢了,TCP的处理方式
    unix 网络编程第八章 UDP
    STDIN_FILENO vs stdin
    unix 网络编程 第七章
    select 实现分析,poll epoll
    pselect 和 select
    export LANG="zh_CN.UTF-8"
    Unix 网络编程 I/O 模型 第六章
  • 原文地址:https://www.cnblogs.com/end-emptiness/p/12013742.html
Copyright © 2020-2023  润新知