pythonunit-testing

Mock.patch function random.random() with return_value depending on the module


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


Solution

  • 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