pkout
pkout

Reputation: 6756

Python: Unit test of a function not returning anything, but changing state of the object

I have a function that doesn't return any value, but changes the internal state of its object. E.g.:

class A(object):
    def __init__(self):
        self._status = None

    def doSomethingThatResultsInChangingStatus(self):
        ...do some computing...
        self._status = newStatus

The _status instance variable is meant to be private, so even though Python technically lets me check its status after the function call, I feel that I shouldn't be doing that. The way I am checking it now is by having a getter function for the _status variable, but that's fundamentally similar to checking the private variable directly. What is the proper way to test this kind of function?

Upvotes: 2

Views: 4521

Answers (3)

boki
boki

Reputation: 194

One option would be to access the private variable through some getter function.

class A:
    def getStatus(self):
         return self._status

Then use this in the assert statement:

def test():
   a.changeStatus()
   assert a.getStatus() == 'newStatus'

[Updated]

Or as suggested by @chepner, use properties:

class A:
    def __init__(self)
        self._status

    @property
    def status(self):
        return self._status

    @status.setter
    def status(self, value):
        self._status = value

And you can access status through a.status.

More info: https://docs.python.org/3/library/functions.html#property

Upvotes: 1

famousgarkin
famousgarkin

Reputation: 14126

Just go ahead and evaluate the _status directly:

def test():
    a = A()
    a.doSomethingThatResultsInChangingStatus()
    assert a._status == 'changed correctly'

That's one of the very reasons we use Python right? To not to have to devise silly contraptions like test-only-wrappers-around-private. Remember, we are all consenting adults here. Private in Python is just to demark members that are not intended for general client usage and may not be safe to use if you don't know what you are doing.

Upvotes: 5

ZZY
ZZY

Reputation: 3947

Does 'doSomethingThatResultsInChangingStatus' return any value? If it returns nothing, you can use its return value to indicate whether status changed.

Or, you can have a self.status_changed member for this purpose. Once changed, set the value to True, and reset to False where applicable

Upvotes: 1

Related Questions