Python 在鼻子里伪造time.time()的时间戳

Python 在鼻子里伪造time.time()的时间戳,python,unit-testing,timestamp,nose,Python,Unit Testing,Timestamp,Nose,我正在用python构建一个设备对象来轮询连接设备的数据,并试图使用nose测试对象及其所有函数的交互工作。使用time.time()编写时间戳时,我通常会遇到一个问题,因为每次调用函数时,结果都不同,这严重影响了一些测试,例如,此数据采集函数: def getData(self, data): if type(data) is not type({}): #print "Bad Type!" raise TypeError else:

我正在用python构建一个设备对象来轮询连接设备的数据,并试图使用nose测试对象及其所有函数的交互工作。使用
time.time()
编写时间戳时,我通常会遇到一个问题,因为每次调用函数时,结果都不同,这严重影响了一些测试,例如,此数据采集函数:

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()
当我测试此函数的输出并比较生成的CSV文件时,由于时间戳,它总是失败。我可以通过添加测试标志在我的设备对象中进行细分,但我想知道nose是否有一种内置的方法来处理类似这样的问题,其中函数的结果可以替换为给定值,或者用一个本地函数来伪造
time.time()
调用。这可能吗?

您可以使用。例如:

import time
from unittest import mock

@mock.patch('time.time', mock.MagicMock(return_value=12345))
def test_something():
    assert time.time() == 12345
生成以下输出:

$ nosetests3 -v
test.test_something ... ok

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

OK
尽管
mock
unittest
包的一部分,但实际上它与任何测试框架都是无关的


对于Python<3.3,您可以使用。

这是从A.C.先前的答案中派生出来的。无需显式创建
MagicMock
。其次,还必须声明mock的用法,以证明其用法

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

这是用Python 3.7测试的。

您可以简单地将time.time()函数分配给自己的函数,并用自己的函数以适当的方式定义时间:

time.time = my_time_function
在单元测试开始时,可以对自己的函数进行赋值,而在测试结束时,会再次恢复原始函数:

class MyTests(unittest.TestCase):
    def get_time(self):
        return self.emulated_time

    def setUp(self):
        # Define the emulated time
        self.emulated_time = time.mktime(
                time.strptime("2020-01-18 02:02:05", "%Y-%m-%d %H:%M:%S"))

        # Register the time.time function and patch it then
        self.time_method = time.time
        time.time = self.get_time

    def tearDown(self):
        # Restore the time.time function
        time.time = self.time_method
    
    def test_time_span(self):
        # Register the start time, do something, emulate a time update of 1
        # second, and check that the execution duration is one second
        start_time = time.time()
        # <do something here>
        self.emulated_time += 1
        self.assertEqual(time.time(), start_time+1)
classmytests(unittest.TestCase):
def获取时间(自我):
返回自我模拟的时间
def设置(自):
#定义模拟时间
self.simulated_time=time.mktime(
time.strtime(“2020-01-18 02:02:05”,%Y-%m-%d%H:%m:%S”))
#注册time.time函数,然后对其进行修补
self.time_方法=time.time
time.time=self.get\u time
def拆卸(自):
#恢复time.time函数
time.time=self.time\u方法
def测试时间跨度(自):
#注册开始时间,做点什么,模拟时间更新1
#然后,检查执行持续时间是否为1秒
开始时间=time.time()
# 
自模拟_时间+=1
self.assertEqual(time.time(),start\u time+1)

这个例子是在Python 3.6.8上测试的。

如果可能的话,我宁愿只使用nose。@Dom:您仍然可以使用nose。我的例子是指鼻子。如果您只想使用nose,那么答案是“您不能”或“编写您自己的模拟模块”。我不相信“模拟的使用也必须被断言”。这当然可能是,取决于可能很重要的测试,但如果不是,测试不会失败。