Home > Software design >  Unittesting some function comprising instance of some class with pytest
Unittesting some function comprising instance of some class with pytest

Time:10-12

Consider the module some_module.py with the following content (in my actual use case, SomeClass and some_function are defined in separate modules):

class SomeClass:
    def __init__(self, v):
        self.some_attr = v

    def some_method(self):
        self.some_attr  = self.some_attr


def some_function(val):
    c = SomeClass(val)
    c.some_method()
    return c

Assume that I have already unittested SomeClass using pytest. Now I want to unittest some_function. My understanding is that I should mock everything related to SomeClass. What I tried was to add the following test function to some_module.py:

def test_some_function(mocker):
    # arrange
    c = mocker.MagicMock()
    c.some_attr = 10

    mocker.patch('some_module.SomeClass', return_value=c)
    mocker.patch('some_module.SomeClass.some_method')
    
    # act
    c = some_function(10)

    # assert
    assert c.some_attr == 20

Running pytest some_module.py in a terminal (obviously) results in failure of the test as c.some_attr is 10. What should the test function look like instead?

CodePudding user response:

In your example, since SomeClass has already been tested successfully and since the purpose of some_function seems to simply be to return an instance of SomeClass for which some_method has been called once and only once, there's no point in mocking it (and it is preferable to avoid mocks when possible).

Therefore, I suggest you test some_function like this:

from some_module import SomeClass, some_function


def test_some_function():

    c = some_function(10)
    assert isinstance(c, SomeClass)
    assert c.some_attr == 20

    c = some_function(-10)
    assert isinstance(c, SomeClass)
    assert c.some_attr == -20

    c = some_function(0)
    assert isinstance(c, SomeClass)
    assert c.some_attr == 0
  • Related