在Angular单元测试中验证ng-pattern

时间:2016-08-12 14:14:18

标签: javascript angularjs unit-testing jasmine

我有下面的一段HTML,它是用一个switch case动态加载的。没有必要为此创建单独的指令,因此我们决定这样做。

<li ng-form="form">
    <input name="number" type="number" ng-model="selectedCriterion.valueFrom" ng-pattern="selectedCriterion.regexPattern">
</li>

使用以下单元测试

describe('form', function() {
    rootScope.selectedCriterion = { regexPattern: '[0-5]+' };

    it('allows numbers to be filled in the input field', function() {
        var compiledElement = $compile(html)(rootScope);
        rootScope.$apply();     
        var form = rootScope.form;
        var inputElement = compiledElement.find('input[name="number"]');

        inputElement.val(4).triggerHandler('input');
        rootScope.$digest();

        expect(inputElement.val()).toEqual('4');
        expect(form.$valid).toEqual(true);

        inputElement.val(8).triggerHandler('input');
        rootScope.$digest();

        expect(inputElement.val()).toEqual('8');
        expect(form.$valid).toEqual(false);
    });
});

我想要做的是在单元测试中测试ng-pattern,而不是在e2e测试级别上测试。 测试在最后的期望中失败

expect(form.$valid).toEqual(false);

似乎表单无法在此级别验证自身,即使我编译HTML并手动调用$ digest循环。

我做错了什么?我可以在此级别验证表单吗?

编辑:我已经深入搜索了StackOverflow和Google,但没有成功。

2 个答案:

答案 0 :(得分:2)

我发现了问题。 就像vbuhlev说的那样,我的代码工作正常,但是它首先不适合我的原因是因为我的输入元素有一个额外的属性,我没有把它放在最初的帖子中,因为我觉得它并不重要。 我的实际输入元素有一个去抖动选项:

<input name="number" type="number" ng-model="selectedCriterion.valueFrom" ng-pattern="selectedCriterion.regexPattern" ng-model-options="{debounce: 200}" >

Karma默认没有考虑到这一点,看到我的表格“有效”而没有等待去抖完成并继续。 我通过使用

刷新任何仍未处理的任务来解决这个问题
$timeout.flush()

这会在检查表单的有效性之前立即执行去抖动。

它现在运行得非常顺利!

答案 1 :(得分:0)

您的代码是正确的!

我已经单独尝试过你的测试了。基本上它和你的一样。

'use strict';

describe('form', function() {

    it('allows numbers to be filled in the input field', inject(function($compile, $rootScope) {
        var html = '<li ng-form="form">'
            + '<input name="number" type="number" ng-model="selectedCriterion.valueFrom" ng-pattern="selectedCriterion.regexPattern">'
            + '</li>';

        $rootScope.selectedCriterion = { regexPattern: '[0-5]+' };
        var rootScope = $rootScope;

        var compiledElement = $compile(html)(rootScope);
        rootScope.$apply();     
        var form = rootScope.form;
        var inputElement = compiledElement.find('input[name="number"]');

        inputElement.val(4).triggerHandler('input');
        rootScope.$digest();

        expect(inputElement.val()).toEqual('4');
        expect(form.$valid).toEqual(true);

        inputElement.val(8).triggerHandler('input');
        rootScope.$digest();

        expect(inputElement.val()).toEqual('8');
        expect(form.$valid).toEqual(false);
    }));
});

你还有其他一些破坏事物的代码。你需要提供更多的背景信息。