Jasmine测试用于输入类型文件并禁用/启用更改事件上的按钮

时间:2016-05-09 06:00:46

标签: jquery jasmine

我想知道Jasmine如何根据更改事件测试启用/禁用输入。我想在一个函数中使用以下代码: -

$('#file-selector').change(function () {
    var file = $('#file-selector').val();
   if (file == '') {
        $('#import').attr("disabled", true);
   } else {
        $('#import').attr("disabled", false);
   }
}); 

这是我到目前为止所处的地方,但我想知道实现这一目标的最佳途径。

beforeEach(function () {
    setFixtures('<div id="file-selector-wrapper">' + '<input id="file-selector" name="xmlFile" type="file" /><span></span></div>' +
        '<button id="import" type="submit" class="btn" disabled="disabled"></button>');
});

it('disables import button when file does not exist', function () {
    var openSpy = jasmine.createSpy('open');
    $("#file-selector").trigger('change');

});

1 个答案:

答案 0 :(得分:1)

应该做一些事情来使您的代码更易于测试,但也涵盖了Jasmine测试中的所有用例。对于这种情况应该有多个测试,而不仅仅是一个。进行更细粒度的测试意味着当一个失败时,跟踪失败的代码会更容易,因为失败的测试覆盖的线路更少。

首先,我建议你的JavaScript看起来像这样: -

$('#file-selector').change(onFileChange);

function onFileChange() {
    var file = $('#file-selector').val();

    if (file == '') {
        $('#import').attr("disabled", true);
    } else {
        $('#import').attr("disabled", false);
    }
}

然后,在您的Jasmine设置中,您可以执行以下操作来测试此功能: -

// mocks
beforeEach(function () {
    var element = document.createElement('input');
    element.id = 'file-selector';
    var import = document.createElement('button');
    import.id = 'import';
    document.body.appendChild(element);
    document.body.appendChild(import);
});

it('calls onFileChange listener when a change has been detected/triggered', function () {
    var spy = spyOn(window, onFileChange); // assuming func is global here
    $('#file-selector').trigger('change');
    expect(spy).toHaveBeenCalled();
});

it('sets the attribute of the import button to false when there is a file', function () {
    document.getElementById('file-selector').value = 'mocked-file';

    onFileChange(); // calls to set attr

    var import = document.getElementById('import').getAttribute('disabled');
    expect(import).toBeFalsy(); // disabled to equal false as mocked file
});

it('sets the attribute of the import button to true when the file is empty', function () {
    document.getElementById('file-selector').value = '';

    onFileChange(); // calls to set attr

    var import = document.getElementById('import').getAttribute('disabled');
    expect(import).tobeTruthy(); // disabled to equal true as no file
});

// empties any previous DOM elements to make tests independent
afterEach(function () {
    var myNode = document.body;
    while (myNode.firstChild) {
        myNode.removeChild(myNode.firstChild);
    }
});

当你用这样的东西测试时,afterEach很重要。清除测试的上下文以使它们保持独立非常重要,并且执行此操作的方式可能会根据测试中涉及的代码而发生变化。

你知道为什么我将改变功能重构为自己的吗?现在,您可以证明在检测到更改时调用了函数,但是在Jasmine中完全独立于该事件测试函数,这意味着您只是测试调用函数时应该发生的核心逻辑。更好的是,将文件选择器输入的值作为参数传递给onFileChange函数会更加温和,这使得测试更加容易。