Dataford
Interview QuestionsInterview GuidesExperiencesMock InterviewsPricing
Get started

Refactor for Testability

MediumCoding00:00
Practice interviewer
In session
5 left
00:00

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).

You need to log in / sign up to chat or submit.

Problem

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.