使用Karma Jasmine-如何测试DOM元素和JavaScript?

3
我一直在努力测试JS和DOM元素,最终找到了可以帮助测试DOM元素的Karma。然而,我目前所做的一切都无法正常工作。非常感谢任何帮助。

我一直在使用这个教程:http://www.bradoncode.com/blog/2015/02/27/karma-tutorial/ ,但无法使其正常工作...

JS:
    window.calculator = window.calculator || {};

    (function() {
        var result;
        var adding = function(one, two) {

            var one1 = document.forms["myForm"]["one"].value;
            var two2 = document.forms["myForm"]["two"].value;

            var one=parseFloat(one.replace(/\,/g,'')); 
            var two=parseFloat(two.replace(/\,/g,''));

            result = parseInt(one1) + parseInt(two2);
            console.log(result);


            var number = document.getElementById("number");
            number.innerHTML = result;
            console.log(one, two, result)
            return result;

        }

        window.calculator.init = function() {
            document.getElementById('add').addEventListener('click', adding);
        };
    })();

HTML:

    <body>
        <form name="myForm">
            <h4>numner 1</h4>
            <input type="text" name="one" id="one"></input>
            <h4>number 2</h4>
            <input type="text" name="two" id="two"></input>

            <input type="button" id="add">
        </form>

        <p id="number"> </p>
        <script type="text/javascript" src="public/adder.js"></script>
        <script>
            calculator.init()
        </script>
    </body>

    </html>

测试规范:

    beforeEach(function() {
        var fixture = '<div id="fixture"> <input type="text" name="one" id="one">' +
            '<input type="text" name="two" id="two">' +
            '<input type="button" id="add" >' +
            '<p id="number"> </p></div>';

        document.body.insertAdjacentHTML(
            'afterbegin',
            fixture);
    });

    // remove the html fixture from the DOM
    afterEach(function() {
        document.body.removeChild(document.getElementById('fixture'));
    });

    // call the init function of calculator to register DOM elements
    beforeEach(function() {
        window.calculator.init();

    });

    it('should return 3 for 1 + 2', function() {
        var x = document.getElementById('one').value = 1;
        var y = document.getElementById('two').value = 2;

        document.getElementById('add').click();

        expect(document.getElementById('number').innerHTML).toBe('3');
    });

document.getElementById('add').click() 对你无效吗?我看到你已经将其注释掉了,我猜想你已经尝试过了? - tehbeardedone
我现在进行了一些更改(编辑了我的代码),但是我一直收到“无法读取未定义属性'one'”的错误。 我认为问题就在这里:var one1 = document.forms [“myForm”] [“one”] .value; 但是我不明白为什么会出现这个问题,而且我不能更改它,因为我需要它。 - javascript2016
这可能是因为您的测试中不存在 myForm。您的测试仅知道您提供的 fixture 元素。从外观上看,fixture 元素需要与您想要测试的元素完全相同。我敢打赌,如果您在 fixture 中添加 myForm 的 HTML,则它将开始工作。 - tehbeardedone
谢谢。我在将HTML元素添加到夹具中遇到了麻烦,因为我会收到错误消息,并且找不到有关如何添加它的信息。我的意思是,当我添加整个HTML文档时,我是否要将其全部放在''中(这会给我带来错误,如果我在包含的每个单个元素周围放置引号,我也会收到错误消息)。它总是:在行(var fixture = ...)中出现无效或意外的标记。现在我没有收到任何错误消息,也不知道为什么。 - javascript2016
我会在午休时间尝试获取一个可以工作的示例,除非有人比我更快地完成并回答。 - tehbeardedone
太好了,非常感谢!!! - javascript2016
1个回答

4
这是一个有效的示例。基本上,我所做的就是在fixture变量中的HTML中添加<form name="myForm"></form>,它就开始工作了。你需要提供一个元素给你的测试,这个元素与你想要在DOM中测试的元素基本相同。你可以省略那些不重要的项目,比如你已经完成的<h4>元素。否则,你需要包括所有将需要进行测试的元素。
在这种情况下,你正在查找表单元素中的值:
var one1 = document.forms["myForm"]["one"].value;
var two2 = document.forms["myForm"]["two"].value; 

var one=parseFloat(one1.replace(/\,/g,'')); 
var two=parseFloat(two2.replace(/\,/g,''));

但您的测试中没有包括表单。您只有两个输入元素、一个按钮和显示结果的元素。下面的代码应该能帮助您正确定位问题。
beforeEach(function() {
    var fixture = '<div id="fixture">' +
        '<form name="myForm">' +            
        '<input type="text" name="one" id="one">' +
        '<input type="text" name="two" id="two">' +
        '<input type="button" id="add" >' +
        '</form>' +
        '<p id="number"> </p></div>';

    document.body.insertAdjacentHTML(
        'afterbegin',
        fixture);
});

// remove the html fixture from the DOM
afterEach(function() {
    document.body.removeChild(document.getElementById('fixture'));
});

// call the init function of calculator to register DOM elements
beforeEach(function() {
    window.calculator.init();

});

it('should return 3 for 1 + 2', function() {
    var x = document.getElementById('one').value = 1;
    var y = document.getElementById('two').value = 2;

    document.getElementById('add').click();

    expect(document.getElementById('number').innerHTML).toBe('3');
});

我可以再问你一个问题吗?在我的实际(更长的)代码中,我的参数不仅包括数字,还包括字符串,而且数字可能包含逗号和点,所以我使用parseFloat(input.replace(/,/g,'')),这很好。只是在测试时,我遇到了“replace is not a function”的错误。你有任何想法为什么只有在测试时才会出现这个错误吗? - javascript2016
如果您能提供一小段代码片段,我稍后有时间会看一下。 - tehbeardedone
谢谢!我已经更新了我的帖子,加入了替换函数(JS部分)。同时我不小心把那个替换函数也更新到了你的帖子里,非常抱歉。 - javascript2016
这是因为您想在输入变量上执行.replace()。应该是var one=parseFloat(one1.replace(/\,/g,''));var two=parseFloat(two2.replace(/\,/g,'')); - tehbeardedone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接