I am trying to learn best practices for OOP and unit testing. I have implemented a simple User class here which checks if the user exists in the database. If yes, then it loads the user data into the instance. If not, then it should create a new entry in the database.
- How should I create unit tests for the methods? For example, for
check_user_exists()should I mock for
existsor three of them? I tried to research for this but none of the tutorials for mocking in Python really gave me any true understanding of how good mocking is done.
- In each of the methods, all the database connection related codes are repeated (i.e.
conn.close()). Can these be refactored away? My guess would be to create a
Databaseclass, but I'm not sure about that.
- Is it weird for
Userclass to have a
database_pathattribute? So far this is the best that I have come up with. Please give any suggestions on how to structure a class where it has to always query databases.
import sqlite3 class User: def __init__(self, username, database_path): self.username = username self.database_path = database_path if not self.check_user_exists(): self.create_user() else: self.get_user() def check_user_exists(self): conn = sqlite3.connect(self.database_path) cursor = conn.cursor() cursor.execute('SELECT rowid FROM user WHERE name = ?', (self.username,)) exists = cursor.fetchone() conn.close() if exists is None: return False else: return True def create_user(self): conn = sqlite3.connect(self.database_path) cursor = conn.cursor() cursor.execute("INSERT INTO user (name) VALUES (?)", (self.username,)) conn.commit() conn.close() def get_user(self): conn = sqlite3.connect(self.database_path) cursor = conn.cursor() cursor.execute("SELECT data FROM user WHERE name=?", (self.username,)) self.data = cursor.fetchone() conn.close()