Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faking a time stamp from time.time() in Nose

I'm building a device object to poll data from connected devices in python and I'm trying to test the inter workings of the object and all it's functions using nose. I am running into a problem in general when writing a timestamp using time.time() as each time the function is called the result the value is different and this seriously screws up some test, for example this data collection function:

def getData(self, data):
    if type(data) is not type({}):
        #print "Bad Type!"
        raise TypeError
    else:
        #print "Good Type!"
        self.outD = {}
        datastr = ""
        for key, value in data.iteritems():
            self.outD[key] = value
        self.outD["timestamp"] = time.time()
        self.outD["id"] = self.id
        self._writeCSV()

When I test the output of this function and compare the generated CSV file, it always fails due to the time stamp. I can sub it out in my device object by adding testing flags, but I was wondering if nose has a built in way to deal with issues like this where the result of a function can be substituted with a given value or a local function to fake the time.time() call. Is this possible?

like image 282
Dom Avatar asked Mar 03 '16 21:03

Dom


2 Answers

You can use unittest.mock. Example:

import time
from unittest import mock

@mock.patch('time.time', mock.MagicMock(return_value=12345))
def test_something():
    assert time.time() == 12345

Produces the following output:

$ nosetests3 -v
test.test_something ... ok

----------------------------------------------------------------------
Ran 1 test in 0.006s

OK

Despite the fact that mock is part of the unittest package, it's actually unrelated and works with any testing framework.

For Python < 3.3, you can use the mock package from PyPI.

like image 83
Andrea Corbellini Avatar answered Nov 11 '22 19:11

Andrea Corbellini


This is derived from the prior answer by A.C. It is not necessary to explicitly create a MagicMock. Secondly, the mock's use must also be asserted to prove its usage.

import time
import unittest.mock

@unittest.mock.patch('time.time', return_value=12345)
def test_foo(mock_time):
    assert time.time() == 12345
    mock_time.assert_called_once()

This was tested with Python 3.7.

like image 6
Asclepius Avatar answered Nov 11 '22 20:11

Asclepius