Home > database >  To mimic os variables in my mock test cases
To mimic os variables in my mock test cases

Time:12-06

I have two python files, the first python file which is triggered in server will dynamically fetch the variable result based on the environment the script is triggered . for an example

for this example, when python script is triggered in dev environment . ideally, ${RPM_ENVIRONMENT} will return as 'DEV'

inside my conf.py file i have below script

import os
import json
import subprocess

import logging
from os import listdir
from os.path import isfile, join

_ENV = os.popen("echo ${RPM_ENVIRONMENT}").read().split('\n')[0]

SERVER_URL = {
    'DEV':{'ENV_URL':'https://dev.net'},
    'UAT':{'ENV_URL':'https://uat.net'},
    'PROD':{'ENV_URL':'https://prod.net'}
}[_ENV]

inside my test cases script , i wanted to mimic as dev environment using unitest mock . i have tried below script but it was returning RPM_ENVIROMENT as key error .

test_env.py

import unittest , sys , tempfile, os , json , shutil
from unittest import mock

with mock.patch.object(os, 'popen') as mock_popen:
    sys.path.insert(1, 'C:/home/test/conf')
    import env_test as conf

I have tried using os.popen to mimic , but i am confused on how i can assign 'DEV' to _ENV variable .

when i tried to run this script, it was returning error as

    SERVER_URL = {
KeyError: <MagicMock name='popen().read().split().__getitem__()' id='1893950325424'

CodePudding user response:

I didn't quite understand if your code is inside a function or not. If it is, the best way to do so is not patch.object. It's just a normal patch:

Consider this example:

def question():
    return os.popen("what_ever").read()


def test_question():
    with patch("os.popen") as popen_mock:
        popen_mock().read.return_value = "DEV"
        actual = question()
    assert actual == "DEV"

In my opinion, patching os.popen and adding read to it's structure is the best practice.

Good luck !

CodePudding user response:

When you mock popen it will return a MagickMock object and that object does not have a defined read response. You need to define what happens when someone calls read() on a MagickMock object that you have returned. Although it is not the most elegant solution, you can do this by adding this line in the with block:

mock_popen.return_value.read.return_value = "DEV"

This will instruct the MagickMock object to return the string "DEV" when read() is called on it.

  • Related