python 跨平台测试:模拟 os.name

Lau*_*ham 5 python testing mocking nose

什么是模拟的正确方法os.name

我正在尝试对一些os.name用于构建适合平台的字符串的跨平台代码进行单元测试。我在 Windows 机器上运行,但想测试可以在 posix 或 windows 上运行的代码。

我试过了:

production_code.py

from os import name as os_name

def platform_string():
    if 'posix' == os_name:
      return 'posix-y path'
    elif 'nt' == os_name:
      return 'windows-y path'
    else:
      return 'unrecognized OS'
Run Code Online (Sandbox Code Playgroud)

test_code.py

import production as production 
from nose.tools import patch, assert_true

class TestProduction(object):
    def test_platform_string_posix(self):
    """
    """
    with patch.object(os, 'name') as mock_osname:
        mock_osname = 'posix'
        result = production.platform_string()
    assert_true('posix-y path' == result)
Run Code Online (Sandbox Code Playgroud)

这失败了,因为os不在test_code.py. 如果 'os' 被import编入,test_code.py那么我们将总是得到os.name=='nt'.

我也试过:

def test_platform_string_posix(self):
    """
    """
    with patch('os.name', MagicMock(return_value="posix")):
        result = production.platform_string()
    assert_true('posix-y path' == result)
Run Code Online (Sandbox Code Playgroud)

在测试中,但这似乎不起作用,因为os.name是属性而不是具有返回值的方法。

编辑:回应评论的澄清

  1. 模拟文档(1段),使它看起来像直接猴子打补丁os.name可能会导致混乱,例如如果断言被上调
  2. 我们实际上只是在更改基于os.name. 虽然测试将在 windows 和 posix 机器上运行,但我想要一些可以全面覆盖的东西,而无需每次进行小编辑时都为机器提供资源。

Mic*_*ico 6

根据在哪里打补丁,你应该打os_name补丁production_code。经过

from os import name as os_name
Run Code Online (Sandbox Code Playgroud)

您正在名为 : 的模块os.name中创建一个 's 引用,之后(在导入时加载)更改没有效果引用。production_codeos_nameos.nameos_name

class TestProduction(object):
    @patch("production_code.os_name","posix")
    def test_platform_string_posix(self):
        assert_equal('posix-y path', production.platform_string())
Run Code Online (Sandbox Code Playgroud)