Your question is Refactor for Testability. Take a moment with it on the right.
Talk me through your thinking if you like. When you're confident, submit your answer and I'll grade it like a real screen (7/10 or better passes).
GIC's portfolio-management platform runs a nightly rebalancing job for each fund it manages. Below is the class a software engineer wrote for it — it works in production, but the team has been unable to write any meaningful unit tests against it.
import datetime
import requests
TARGET_WEIGHTS = {"AAPL": 0.2, "MSFT": 0.2, "TSM": 0.3, "ASML": 0.3}
class PortfolioRebalancer:
def __init__(self, fund_id):
self.fund_id = fund_id
self.db = PostgresClient("prod-db.gic.internal", "portfolio")
self.market_data = requests.Session()
self.last_run = None
def rebalance(self):
holdings = self.db.query(f"SELECT * FROM holdings WHERE fund_id = {self.fund_id}")
prices = self.market_data.get("https://market-feed.internal/prices").json()
trades = []
for h in holdings:
current_value = h["shares"] * prices[h["ticker"]]
target_value = TARGET_WEIGHTS[h["ticker"]] * self._total_value(holdings, prices)
if abs(current_value - target_value) > 1000:
trades.append({"ticker": h["ticker"], "delta": target_value - current_value})
self.last_run = datetime.datetime.now()
self.db.execute("INSERT INTO rebalance_log VALUES (%s, %s)", (self.fund_id, self.last_run))
return trades
def _total_value(self, holdings, prices):
return sum(h["shares"] * prices[h["ticker"]] for h in holdings)
How would you refactor this code to make it more testable? Explain, for each specific obstacle in this class, why it blocks a unit test today and what you'd change.