测试是否已在python中初始化某些字段

时间:2014-09-25 11:54:27

标签: python mocking

我正在尝试用Python编写一个测试,检查我正在编写的类中的方法是否为某个Hdf文件中的数据集设置了属性值。逻辑如下:通过传递 h5py.File 的实例来构造类的实例,然后一个方法在此文件中创建数据集。在下一步中,我有另一种方法为该数据集设置某些属性。

我要测试的是,如果我的类方法 create_attributes(self,attributes)将字段 hdf_file [dset_name] .attrs [attr_name] 设置为某个值在变量 attributes 中传递。但是,我想避免实际创建一个Hdf文件。到目前为止,我已经尝试模拟一个hdf文件的实例并使用它。最小工作代码示例如下:

import h5py

class TestSomething:
    @mock.patch('h5py.File')
    def test_if_attr_is_initialized(self,mock_hdf):
        # Here I would like to call a function that basically executes
        # the following line:
        mock_hdf['test_dset'].attrs['test_field']='value'

        # Then I want to check if the attribute field has been assigned
        assert mock_hdf['test_dset'].attrs['test_field']=='value'

有人可以帮我找到正确的方法来检查hdf文件中的属性是否设置正确吗?任何帮助将不胜感激,我是所有嘲弄技术的完全新手。

编辑:

在下文中,我提供了类的最小代码示例,以及wwii重新发布的相应测试:

import h5py

class HdfWriter():
     def __init__(self,hdf_file):
         self.hdf_file=hdf_file

     def create_attrs(self,attributes):
         dset_name=attributes.keys()[0]
         attrs=attributes[dset_name]

         for key in attrs:
             self.hdf_file[dset_name].attrs[key]=attrs[key]

请注意,使用真正的hdf文件,我首先必须创建一个数据集,但我想将其留给另一个测试。以下测试应该检查,是否对于具有数据集 test_dset 的假设hdf文件,写入了该数据集的属性:

import h5py
import HdfWriter

class TestSomething:
    @mock.patch('h5py.File')
    def test_if_attr_is_initialized(self,mock_hdf):
        writer=hw.HdfWriter(mock_hdf)
        attr={'test_dset':{'test_field':'test_value'}}
        writer.create_attrs(attr)

        assert writer.hdf_file['test_dset'].attrs['test_field']=='value'

1 个答案:

答案 0 :(得分:2)

模拟h5py.File

class HdfWriter():
     def __init__(self,hdf_file):
         self.hdf_file=hdf_file

     def create_attrs(self,attributes):
         dset_name=attributes.keys()[0]
         attrs=attributes[dset_name]

         for key in attrs:
             self.hdf_file[dset_name].attrs[key]=attrs[key]

出于create_attrs方法的目的,hdf_file表现为一个字典,它返回一个行为类似于字典的对象。文档非常清楚地解释了如何模拟字典。

您需要一个具有attrs属性的模拟,其行为类似于字典:

import mock

attrs_d = {}
def setattrs(name, value):
##    print 'setattrs', name, value
    attrs_d[name] = value
def getattrs(name):
##    print 'getattrs', name
    return attrs_d[name]
mock = mock.MagicMock()
mock.attrs.__setitem__.side_effect = setattrs
mock.attrs.__getitem__.side_effect = getattrs

您需要hdf_file的模拟,其行为类似于字典,并将返回上面创建的模拟对象。

hdf_d = {'test_dset':mock}
def getitem(name):
##    print 'getitem', name
    return hdf_d[name]
def setitem(name, value):
    hdf_d[name] = value
mock_hdf = mock.MagicMock()
mock_hdf.__getitem__.side_effect = getitem
mock_hdf.__setitem__.side_effect = setitem
实施后,

hdf_d仅适用于密钥'test_dset'。根据您的需要,getitems可能更好地返回mock,无论名称参数如何。

def test_if_attr_is_initialized(mock_hdf):
    writer=HdfWriter(mock_hdf)
    attr={'test_dset':{'test_field':'test_value'}}
    writer.create_attrs(attr)
    print writer.hdf_file['test_dset'].attrs['test_field'], '==', attr['test_dset']['test_field']

    assert writer.hdf_file['test_dset'].attrs['test_field']=='test_value'

test_if_attr_is_initialized(mock_hdf)

>>> 
test_value == test_value
>>> 

这应该足以测试create_attrs,但它可能不是最佳的 - 也许有人会进行一些改进。