3

In an interview, they asked me to write a program to get current (live) time of given states in a list. I have written the code for it and was asked to tell how I would test the program to check if the output having time is correct.

I was stuck as to how will I be verifying as I won't get the exact time later on.

How would we be testing this?

2 Answers 2

3

There are two main options here: dependency injection or mocking. Dependency injection in your case would mean that the program would take a reference to the source of temperature data, which you can then fake in order to check that the code is doing the right thing at the interface to the temperature source. Alternatively you can mock the source of temperature data by basically replacing the source of the temperature data with a convenient set of numbers.

Dependency injection is the preferred method, since it makes it obvious which external sources of data your program depends on. Mocking is easier with legacy code, but tends to make your tests hard to follow — mocking is effectively interpreter or compiler magic — and brittle, since your tests now depend on (lower level than DI) implementation details.

Example of code where you can test with "current" time to your heart's content:

import datetime
from typing import Callable


def something_with_time(clock: Callable[[], datetime.datetime]) -> None:
    while True:
        now = clock()
        …

As you can see that is easily unit tested — test code will pass a function returning whatever you want (including exactly midnight, timezone transitions, leap seconds, etc.), and production code will pass a function like datetime.datetime.now. Mocking with legacy code example:

import datetime
import unittest
from unittest import mock


def something_with_time():
    while True:
        now = datetime.datetime.now()
        …


class SomethingWithTimeTests(unittest.TestCase):
    @mock.patch('datetime.datetime.now', [datetime.datetime(2000, 1, 1), datetime.datetime(2000, 1, 2)])
    def test_should_something_something(self) -> None:
        self.assertSomething(something_with_time())
1

Another option on the mocking route mentioned by l0b0 is freezegun, which overrides all of the built-in time generation utilities for you:

import unittest

from freezegun import freeze_time

@freeze_time("1955-11-12")
class MyTests(unittest.TestCase):
    def test_your_function(self):
        ...

This requires installation of a third party library, but is generally more readable than mocking e.g. now yourself and has the ability to do things like keep ticking during the test.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.