1

I want to replace randint in the method multi with 'mock' in Python. My code doesn't work. How can I make it work?

from random import randint
import unittest
from unittest import mock


class Calculator:

    def __init__(self, number):
        self.number = number
        self.number2 = randint(1, 5)

    def multi(self):
        return self.number * self.number2


class CalculatorTest(unittest.TestCase):

    NUMBER = Calculator(3)

    @mock.patch('random.randint', return_value=4)
    def test_multi(self):
        actual_result = self.NUMBER.multi()
        expected_result = 12
        self.assertEqual(actual_result, expected_result,
                         f'Actual result {actual_result}, expected {expected_result}')
1
  • 1
    What are the requirements for you program? Commented Sep 3, 2021 at 17:14

1 Answer 1

2

You are calling randint when NUMBER is defined, not when you call its multi method. The patch is too late. Instead, define NUMBER in the test itself. Further, since you used from random import randint, the name to patch is randint, not random.randint.

class CalculatorTest(unittest.TestCase):

    @mock.patch('randint', return_value=4)
    def test_multi(self, mock_rand):
        NUMBER = Calculator(3)
        actual_result = NUMBER.multi()
        expected_result = 12
        self.assertEqual(actual_result, expected_result,
                         f'Actual result {actual_result}, expected {expected_result}')

If NUMBER must be defined as class attribute (though that would be atypical), you can use mock.patch as a context manager rather than a decorator.

class CalculatorTest(unittest.TestCase):

    with mock.patch('randint', return_value=4)
        NUMBER = Calculator(3)

    def test_multi(self):
        actual_result = self.NUMBER.multi()
        expected_result = 12
        self.assertEqual(actual_result, expected_result,
                         f'Actual result {actual_result}, expected {expected_result}')

More commonly, though, you would use the setUp method to define a fixture, rather than sharing an instance across tests. You can either decorate setUp or us the context manager.

class CalculatorTest(unittest.TestCase):

    def setUp(self):
        with mock.patch('randint', return_value=4):
            self.NUMBER = Calculator(3)

    ...

or

class CalculatorTest(unittest.TestCase):

    @mock.patch('randint', return_value=4)
    def setUp(self, mock_rand):
        self.NUMBER = Calculator(3)

    ...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.