【发布时间】:2014-09-25 16:34:32
【问题描述】:
我在进行单元测试时遇到了困难,我想在其中验证文件的处理,通常通过<input type='file'> 在视图中选择该文件。
在我的 AngularJS 应用程序的控制器部分,文件在输入的更改事件中处理,如下所示:
//bind the change event of the file input and process the selected file
inputElement.on("change", function (evt) {
var fileList = evt.target.files;
var selectedFile = fileList[0];
if (selectedFile.size > 500000) {
alert('File too big!');
// ...
我希望evt.target.files 在我的单元测试中包含我的模拟数据,而不是用户选择的文件。我意识到我不能自己实例化 FileList 和 File 对象,这将是浏览器正在使用的相应对象。因此,我将模拟 FileList 分配给输入的 files 属性并手动触发更改事件:
describe('document upload:', function () {
var input;
beforeEach(function () {
input = angular.element("<input type='file' id='file' accept='image/*'>");
spyOn(document, 'getElementById').andReturn(input);
createController();
});
it('should check file size of the selected file', function () {
var file = {
name: "test.png",
size: 500001,
type: "image/png"
};
var fileList = {
0: file,
length: 1,
item: function (index) { return file; }
};
input.files = fileList; // assign the mock files to the input element
input.triggerHandler("change"); // trigger the change event
expect(window.alert).toHaveBeenCalledWith('File too big!');
});
不幸的是,这会导致控制器中出现以下错误,表明此尝试失败,因为文件根本没有分配给输入元素:
TypeError: 'undefined' 不是对象(评估 'evt.target.files')
出于安全原因,我已经发现 input.files 属性是只读的。所以我开始了另一种方法,通过调度一个定制的更改来提供 files 属性,但仍然没有成功。
长话短说:我很想学习一个可行的解决方案或任何关于如何处理这个测试用例的最佳实践。
【问题讨论】:
-
你使用的是 jQuery 还是 jqLite?
-
在新的 Blobs() 上添加一些道具应该会让你得到一些像 File() 一样嘎嘎作响的东西......
标签: javascript angularjs unit-testing jasmine