admin管理员组

文章数量:1434221

Intention: I am trying to create a unit test for a complex class, where a lot of values are randomly generated by using random.random(). To create a unit test, I want to use mock.patch to set fixed values for random.random(), to receive always same values (same configuration) and then I can run my test which must have always same result.

Problem: I need to patch function random() from random library with values depending on the module. In my understanding, mock.patch('modul1.random.random', return_value=1) should only influence the modul1 and no other random() functions in other modules. The same for the modul2:

modul1.py:

import random

def function():
    return random.random()

modul2.py:

import random

def function():
    return random.random()

The unit_test:

def test_function():
    with mock.patch('modul1.random.random', return_value=1), \
         mock.patch('modul2.random.random', return_value=0):
        val1 = modul1.function()
        val2 = modul2.function()
        assert not val1 == val2

Expectation: val1 = 1 and val2 = 0, therefore passed

Reality: assert not 0 == 0 PythonCodebase/tests/test_patient.py:55: AssertionError

Intention: I am trying to create a unit test for a complex class, where a lot of values are randomly generated by using random.random(). To create a unit test, I want to use mock.patch to set fixed values for random.random(), to receive always same values (same configuration) and then I can run my test which must have always same result.

Problem: I need to patch function random() from random library with values depending on the module. In my understanding, mock.patch('modul1.random.random', return_value=1) should only influence the modul1 and no other random() functions in other modules. The same for the modul2:

modul1.py:

import random

def function():
    return random.random()

modul2.py:

import random

def function():
    return random.random()

The unit_test:

def test_function():
    with mock.patch('modul1.random.random', return_value=1), \
         mock.patch('modul2.random.random', return_value=0):
        val1 = modul1.function()
        val2 = modul2.function()
        assert not val1 == val2

Expectation: val1 = 1 and val2 = 0, therefore passed

Reality: assert not 0 == 0 PythonCodebase/tests/test_patient.py:55: AssertionError

Share Improve this question edited Nov 18, 2024 at 17:57 Wyck 11.9k8 gold badges48 silver badges82 bronze badges asked Nov 18, 2024 at 13:23 chochfchochf 455 bronze badges 7
  • @Wyck Ok, to my original problem. I have a class Patient which has certain parameters which some of them are randomly generated. Also class Patient contains instance of two classes which have also some randomly generated parameters. So for each unit test, I want to guarantee the same configuration. Then I simulate the patient and check if the results have the given values. – chochf Commented Nov 18, 2024 at 13:38
  • 1 For the unit test, I am setting fix values instead of the random onces (use of mock.patch). I want the random function in modul1 always return 1 in the unit test and for the modul 2 always return 0 in the unit test. Why both return 0, that is the question I am interested in. So the mock.patch doesnt work for me as intended. – chochf Commented Nov 18, 2024 at 13:48
  • 1 Ah, I see now. It's probably a good idea to edit your question and add that detail directly to the body of the question. – Wyck Commented Nov 18, 2024 at 13:51
  • I'm not experienced enough to know how mock.patch works, but are you sure that module1.random.random is the thing you want to patch? From your description, it sounds like the idea is to patch modul1.function. I guess you're hoping that it's possible to patch random.random two different ways, depending on which module it's imported into? (I don't know how to do it - but I'm just trying to clarify your expectations) – Wyck Commented Nov 18, 2024 at 14:00
  • 1 It's wrong because there is only one module random to patch. If you want your two modules to use two different functions, they have to use two different functions in the first place. – chepner Commented Nov 18, 2024 at 15:00
 |  Show 2 more comments

2 Answers 2

Reset to default 1

There is only function to patch, random.random, and it's shared by both modules. The best you can do is use side_effect to provide two values for it to return, one per call, but that requires you to know the order in which modul1.function and modul2.function will be called, and that may not be predictable.

Better would be to modify the two modules to use their own names to refer to random.random; then you can patch those two names separately.

modul1.py:

from random import random

def function():
    return random()

modul2.py:

from random import random

def function():
    return random()

The unit_test:

def test_function():
    with mock.patch('modul1.random', return_value=1), \
         mock.patch('modul2.random', return_value=0):
        val1 = modul1.function()
        val2 = modul2.function()
        assert not val1 == val2

As @chepner mentioned there is only one module random to patch it is wrong, maybe you can update your code like below that way your issue should be resolved. let me know if issue still seen

modul1.py:

from random import random

def function():
    return random()

modul2.py:

from random import random

def function():
    return random()

The unit_test:

def test_function():
    with mock.patch('modul1.random', return_value=1), \
         mock.patch('modul2.random', return_value=0):
        val1 = modul1.function()
        val2 = modul2.function()
        assert not val1 == val2

本文标签: pythonMockpatch function randomrandom() with returnvalue depending on the moduleStack Overflow