在最简单的测试中,我尝试测试以下函数:
addPercentSign: function (oEvent, control) {
var inputVal = oEvent.getParameters().value;
var inputNumber = parseFloat(inputVal);
if (inputNumber) {
if (inputNumber < 50 || inputNumber > 100) {
//see learningCurveFormatCheck
return null;
} else {
var finalVal = inputNumber.toFixed(1);
var finalOutput = finalVal + "%";
control.learningCurve.setValue(finalOutput);
return finalOutput;
};
}
}
上述函数是输入字段 (id="learningCurveInput") 上的事件监听器。当用户在字段中键入一个值然后触发“提交”事件(通过“ENTER”键)时,将调用“addPercentSign”函数。
我理解单元测试的想法是尽可能地将测试与任何依赖项“隔离”。因此,要针对 DOM 操作进行测试,可以将元素附加到 div 下的 test.html,如下所示:
$('<input id="learningCurveInput" type="text"/>').appendTo('#qunit-fixture');
谁能解释一下接下来要做什么?该函数依赖于传入的 Event 对象来检索输入值。我不确定如何在测试中重新创建它。我在下面附上了我的单元测试,但这只是为了展示我的想法:
...,
function (formatter, viewControls) {
"use strict";
QUnit.module("Formatter Object Exists")
QUnit.test("Learning Curve Input Value", function (assert) {
$('<input id="learningCurveInput" type="text"/>').appendTo('#qunit-fixture');
$("#learningCurveInput").val("55");
var result = '55';
equals(result, $('#learningCurveInput').val(), "testing input value");
});
QUnit.test("addPecentSign Function", function (assert) {
//how to test this dom-dependent function?
});
}
);
总结问题
如何对输入字段的“提交”时调用的“addPercentSign”函数进行单元测试?
最佳答案
我建议将它分成这些部分:
"51"-> "51.0%"input值的方法是否有效如果所有这些测试都成功,您可以假设将它们链接在一起也能正常工作。
为了测试转换方法,我建议将其逻辑移动到一个单独的纯函数中。我在下面粘贴了您的格式逻辑并删除了 setValue 副作用。我包括了一些测试(你应该检查它们,看看你是否需要更多/它们符合你的要求)。我留下了两个失败的测试作为例子。
function addPercentSign(val) {
var inputNumber = parseFloat(val);
if (inputNumber) {
if (inputNumber < 50 || inputNumber > 100) {
//see learningCurveFormatCheck
return null;
} else {
var finalVal = inputNumber.toFixed(1);
var finalOutput = finalVal + "%";
return finalOutput;
};
};
};
module("String formatting");
test("Returns undefined for unparseable strings", function() {
["foo", null, NaN, "0.0.0"]
.forEach(function(result, i, arr) {
var result = addPercentSign(result);
strictEqual(result, undefined, arr[i] + " produces " + result);
});
});
test("Returns null for values below 50 and above 100", function() {
["0", "0.0", "25", "49.99999", "100.00000001", "10300", Infinity]
.forEach(function(result, i, arr) {
var result = addPercentSign(result);
strictEqual(result, null, arr[i] + " produces " + result);
});
});
test("Appends a % sign for values between 50 and 100", function() {
strictEqual(addPercentSign("51.0"), "51.0%");
// ...
});
test("Appends a digit for values without one", function() {
strictEqual(addPercentSign("51"), "51.0%");
// ...
});
test("Removes and rounds digits for values with more than one", function() {
strictEqual(addPercentSign("51.999"), "52.0%");
strictEqual(addPercentSign("51.06"), "51.1%");
// ...
});<link href="https://code.jquery.com/qunit/qunit-1.12.0.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/qunit/qunit-1.12.0.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
既然您已经了解了这个方法,您将需要确定是否可以从 检索值并将值写入 输入字段。这些与您已经写过的类似:
值function createInput() {
return $('<input id="learningCurveInput" type="text" value="hello world"/>')
.appendTo('#qunit-fixture');
}
module("Writing and reading to input", {})
test("writes to value", function(assert) {
var $input = createInput();
var result = "55";
// Whatever you're using to set:
// in your code, I read `control.learningCurve.setValue`
// if that's what you're using, that's the method you should test
$input.val(result);
strictEqual($input.val(), result);
});
test("reads from value", function(assert) {
var $input = createInput();
// Whatever you're using to get the value
$input.val();
strictEqual($input.val(), "hello world");
});<link href="https://code.jquery.com/qunit/qunit-1.12.0.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/qunit/qunit-1.12.0.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
现在您知道您可以 (a) 正确地转换值,以及 (b) 正确地读取和写入值,您需要测试您的get value -> transform value -> set value 序列将由正确的输入触发。例如:
jQuery 有一些方便的方法来附加和触发事件监听器。您可以使用不带参数的 .change 或 submit 来模拟 UI 输入。或者,您可以触发提交按钮上的点击。
function createForm() {
return $("<form></form>")
.append(createInput());
}
function createInput() {
return $('<input id="learningCurveInput" type="text" value="hello world"/>')
.appendTo('#qunit-fixture');
}
module("Form event listeners", {})
test("input executes method on change", function(assert) {
var called = false;
var onChange = function() { called = true; };
var $input = createInput();
$input.change(onChange);
$input.val("test");
strictEqual(called, false);
$input.change();
strictEqual(called, true);
});
test("form executes method on submit", function(assert) {
var called = false;
var onSubmit = function() { called = true; };
var $form = createForm();
var $input = $form.find("input");
$form.submit(onSubmit);
strictEqual(called, false);
$form.submit();
strictEqual(called, true);
});<link href="https://code.jquery.com/qunit/qunit-1.12.0.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/qunit/qunit-1.12.0.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
现在,您可以确定您的代码的实现是否包含在您的测试中:
$("form").submit(function() { // Tested in test 3
var $input = $(this).find("input");
var originalValue = $input.val(); // Tested in test 2
var newValue = addPercentSign(originalValue); // Tested in test 1
$input.val(newValue); // Tested in test 2
});
请注意,它主要是具有自定义逻辑和要求的第一个测试模块。如果您使用的是已经过严格测试的 jQuery,则无需为 .val() 等方法重新实现测试:检查它们的公共(public)存储库以了解这些方法的覆盖范围。如果您要实现与 DOM 交互的自定义方法,您确实需要测试它们。
因此,简而言之:将 addPercentageSign 重写为一个接受字符串并返回字符串的纯函数;确保它经过彻底测试。通过经过测试的库与 DOM 交互,或者为 DOM 编辑和事件监听编写测试。
关于javascript - 如何在输入字段上对事件监听器进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41069515/
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121
这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式rubyshell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f