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.