我有一个Python类,其__init__
方法引发了一个名为WrongFileSpecified
的自定义异常。
但是,当我编写单元测试时,我想从测试夹具中分配实例对象的属性。所以通常我要做的是从文件中读取数据然后使用实例对象。
但是通过测试,我无法使用任何测试文件,因此我基本上需要在单元测试的setUp
方法中对实例对象中的数据进行硬编码。有没有办法在没有__init__
抱怨异常的情况下创建实例?
示例代码:
class A(object):
def __init__(self, folderPath):
#check folder path using os.isdir() otherwise raise exception
#...
self.folderPath = folderPath
#Call load record
self._load_records() #uses self.folderPath and raises exceptions as well
#Note i cannot avoid raising these exceptions, its required
class TestA(unittest.TestCase):
.......
obj = None
def setUp(self):
obj = A('fake folder path')
obj.val1 = "testparam1"
obj.param2 = "testparam2"
def test_1(self):
.....
答案 0 :(得分:1)
您可以使用var outputReport = '';
var uidList = [];
$(function() {
var listSource =
{
datatype: "json",
dataFields : [ {
name : "First",
type : 'string'
}, {
name : "Last",
type : 'string'
} ],
id: 'id',
localdata: [{'id': 1, 'First': 'Abhishek', 'Last': 'Shringi'},{'id': 2, 'First': 'Abhishek', 'Last': 'Shringi'},{'id': 3, 'First': 'Abhishek', 'Last': 'Shringi'},{'id': 4, 'First': 'Abhishek', 'Last': 'Shringi'},{'id': 5, 'First': 'Abhishek', 'Last': 'Shringi'},{'id': 6, 'First': 'Abhishek', 'Last': 'Shringi'}]
};
var listAdapter = new $.jqx.dataAdapter(listSource);
//Dropdown source for PW Reset
var dropDownListSource =
{
datatype: "json",
datafields: [
{ name: 'name' }
],
id: 'id',
localdata: [{'id': 1, 'name': 'New'},{'id': 2, 'name': 'Yes'},{'id': 3, 'name': 'No'}]
};
var dropdownListAdapter = new $.jqx.dataAdapter(dropDownListSource, { autoBind: true, async: false });
var dropdownListSource = [];
for (var i = 0; i < dropdownListAdapter.records.length; i++) {
dropdownListSource[i] = dropdownListAdapter.records[i]['name'];
}
// create list user grid
$('#list-users-table').jqxGrid({
source : listAdapter,
altrows: true,
autoheight: true,
width: '99%',
columnsheight: 30,
editable: true,
editmode: 'click',
pagesizeOptions: ['2','4','6','8'],
pagesize: 2,
pageable: true,
filterable: true,
sortable: true,
virtualmode: true,
selectionmode: 'multiplerowsextended',
filtermode: 'default',
rendergridrows: function(params) {
return params.data;
},
handlekeyboardnavigation: function(e)
{
var key = event.charCode ? event.charCode : event.keyCode ? event.keyCode : 0;
if (key == 39) {
$("#list-users-table").jqxGrid('gotonextpage');
}
else if (key == 37) {
$("#list-users-table").jqxGrid('gotoprevpage');
}
e.stopPropagation();
e.event.cancelbubble = true;
},
columnsresize: true,
showheader: true,
columns : [ {
text : 'PW Reset',
datafield : 'Reset',
width : 80,
columntype: 'dropdownlist',
initeditor: function (row, cellvalue, editor) {
editor.jqxDropDownList({ source: dropdownListSource});
editor.on('select', function(event) {
var args = event.args;
if (args) {
var index = args.index;
var item = args.item;
var resetType = item.label;
var value = item.value;
var selection = $("#list-users-table").jqxGrid('getselectedrowindexes');
if (selection
&& selection.length > 0) {
for (var i = 0; i < selection.length; i++) {
var rowData = $('#list-users-table').jqxGrid('getrowdata', selection[i]);
}
}
}
});
}
}, {
text : 'First Name',
datafield : 'First',
width : 120,
editable : false,
align: 'center'
}, {
text : 'Last Name',
datafield : 'Last',
width : 120,
editable : false,
align: 'center'
}
]
});
//function calls when apply filter
$('#list-users-table').on('filter', function (event) {
if(event.args.filters.length > 0) {
$("#export-user-menu-item").show();
} else {
$("#export-user-menu-item").hide();
}
$('#list-users-table').jqxGrid('updatebounddata', 'filter');
$("#list-users-table").jqxGrid('clearselection');
});
//function calls when apply sorting
$('#list-users-table').on('sort', function (event) {
$('#list-users-table').jqxGrid('updatebounddata', 'sort');
$("#list-users-table").jqxGrid('clearselection');
});
});
绕过__init__
来创建一个空对象。
__new__
请注意,obj = obj_type.__new__(obj_type)
是适当的obj_type
对象。这有点hacky但它的工作原理。您负责设置对象的成员。
编辑:这是一个例子。
type
控制台输出:
class Foo():
def __init__(self):
self.x = 1
self.y = 2
def say_hello(self):
print('Hello!')
r = Foo.__new__(Foo)
r.say_hello()
print(r.x)
答案 1 :(得分:0)
以下是两个选项:
__init__
提供一个额外参数,以便在必要时(例如def __init__(self, folderPath, suppress=False)
或validate=True
禁止例外情况,无论哪种情况对您的使用更有意义)。在我看来,后者有点尴尬,但这意味着您不必重构现有代码来创建A
个实例。前者看起来像:
class A(object):
def __init__(self, ...):
"""Pass whatever is loaded from the file to __init__."""
...
@classmethod
def from_file(cls, folderPath):
"""Load the data from the file, or raise an exception."""
...
你会替换例如a = A(whatever)
与a = A.from_file(whatever)
。
答案 2 :(得分:0)
有一个名为mock
的非常有用的模块,你可以稍后查看,我觉得在这种情况下它会太多了。相反,您应该考虑重新设计您的课程,例如:
class A(object):
def __init__(self, folderPath):
self.folderPath = folderPath
def _load_records(self)
#check folder path using os.isdir() otherwise raise exception
...
#uses self.folderPath and raises exceptions as well
...
@classmethod
def load_records(cls, folderpath):
obj = cls(folderpath)
obj._load_records()
return obj
# Usage
records = A.load_records('/path/to/records')
然后你可以这样做:
class TestA(unittest.TestCase):
.......
obj = None
def setUp(self):
self.obj = A('fake folder path')
self.obj.val1 = "testparam1"
self.obj.param2 = "testparam2"
def test_1(self):
self.assertRaises(self.obj._load_records, HorribleFailureError)
此外我强烈建议您查看pytest,它有很棒的测试设施,包括文件夹和文件夹。