mardi 26 mai 2015

python cross platform testing: mocking os.name

what is the correct way to mock os.name?

I am trying to unittest some cross-platform code that uses os.name to build platform-appropriate strings. I am running on a Windows machine but want to test code that can run on either posix or windows.

I've tried:

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'

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)

this fails because os is not in the global scope for the test_code.py. If 'os' is imported in test_code.py then we will always get os.name=='nt'.

I've also tried:

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

in the test, but this seems not to work because os.name is an attribute not a method with a return value.

Aucun commentaire:

Enregistrer un commentaire