Home > Net >  implementing Unittest for property decorator
implementing Unittest for property decorator

Time:04-28

I've got this code that gathers the first name of a person.

class Person:

   #initializing the variables and giving them an empty string as a baseline.
    def __init__(self, first_name = '', last_name = ''):
        self.first_name = first_name
        self.last_name = last_name


    @property
    #getting first name and returning it for future use.
    def first_name(self):
        return self._first_name
    

    #setting the first name
    @first_name.setter
    def first_name(self, first_name):
        #capitalizing the first name.
        self._first_name = first_name.capitalize()


    @property
    #getting last name and returning it for future use.
    def last_name(self):
        return  self._last_name


    @last_name.setter
    #setting last name
    def last_name(self, last_name):
        #capitalizing last name    
        self._last_name = last_name.capitalize()

and I want to create a unittest that tests the class/first_name/property decorator, and I wanted to see if I was going about it the right way?

import unittest
from person import Person
class TestPerson(unittest.TestCase):

    def test_first_name(self):
        Person._first_name = first_name('FakeName')
        self.assertEqual(Person._first_name(), 'FakeName')

    #updated code to fix errors pointed out. The first name works!
    #the last name does not.
    def test_last_name(self):
        testLast = Person('LastName')
        #Throws assertion error '' != 'LastName here. 
        self.assertEqual(testLast.last_name, 'LastName')

if __name__ == "__main__":
    unittest.main()

The unittest coding runs and passes without error, but I was wondering if it was using the property decorator at all? I'm a bit of a newbie when it comes to decorators and unittesting, so I wanted to make sure this was actually using the property decorator rather than bypassing it, or if I should be formatting it some other way(or using unittest.mock, as a few other forums have suggested, but I'm not familiar with .mock at all).

EDIT: Because I was totally smart at 3 in the morning, I completely bypassed actually setting a class that inherits from unittest. This has been adjusted in the second code clip. Also added my last_name to the Person and unittest for more information on how the two should be interacting.

EDIT 2: All code has been adjusted to the edits suggested. Thank you everyone! Will continue to slowly fix my errors haha.

CodePudding user response:

First, let's fix the class before you worry about testing it.

class Person:

    def __init__(self, first_name=''):
        self.first_name = first_name

    @property
    def first_name(self):
        return self._first_name
    
    @first_name.setter
    def first_name(self, first_name):
        self._first_name = first_name.capitalize()

    @property
    def last_name(self):
        return  self._last_name

    @last_name.setter
    def last_name(self, last_name):
        #capitalizing last name    
        self._last_name = last_name.capitalize()

Only the getter and setter interact directly with the _first_name attribute, and the property name itself should be part of the public interface (i.e., not prefixed with a _). (Note that the property and the backing attribute cannot share the same name.)

Now, the test:

import unittest
from person import Person

class TestPerson(unittest.TestCase):
    def test_first_name(self):
        p = Person('fakeName')
        self.assertEqual(p.first_name, 'FakeName')


if __name__ == "__main__":
    unittest.main()

You need to create an instance of Person, then check that the value returned by the property matches the expected name. For this example, I passed a non-capitalized name to Person to check that the setter capitalizes it as expected.

Also, the test method must be an instance method of (a subclass of) unittest.TestCase for unittest.main to find and run it. main looks for appropriately named classes, instantiates them, then runs appropriately named methods with those instances.

  • Related