情况: 我刚刚开始学习单元测试我的JavaScript代码,我想知道是否有办法伪造应用程序的行为以测试某些情况。我读到了关于sinon.js spy / stub / mock的内容。然而,像往常一样,JS有很多进一步的脚本和组合(即与mocha,chai,karma-jasmine),我希望有人可以告诉我一个最佳实践。
让我们举个例子: 如果我想在测试运行器中测试一个函数,它根据窗口大小改变背景大小,触发不同的窗口大小(而不是元素大小)以查看多个工作的背景大小调整是很复杂的尺寸。
我已经测试过一些东西,例如
var resizeW = sinon.stub($.prototype, 'width').returns(600);
var resizeH = sinon.stub($.prototype, 'height').returns(1600);
// no effect - always takes the original view.height/width
viewport.setAttribute("content", "height=" + viewheight + "px, width=" + viewwidth + "px, initial-scale=1.0");
// new window is not testable in the root testrunner window
window.open + window.resizeTo() / window.resizeBy()
// shows no effect
window.innerHeight = '120'; window.innerWidth = '500';
// provides no possibility to assume different dimensions
$(window).trigger('resize');
// provides no possibility to assume different dimensions
$(document).trigger('resize');
// provides no possibility to assume different dimensions
window.dispatchEvent(new Event('resize'));
使用iframe将是乏味的,即通过与原始HTML和testrunner HTML之间的CSS和jQuery冲突。
我希望有人可以建议一种方便的方法来实现这一目标。
答案 0 :(得分:2)
单元测试旨在断言应用程序的逻辑和状态位按预期工作。
虽然你肯定可以在浏览器中设置一个单元测试套件来对应你的应用程序表示层断言,但可能不是这样,因为你知道,很难模拟一些浏览器行为强>
正如@SteveB在他的评论中所说,端到端测试的工具可能比单元测试更适合你。这些工具允许在浏览器中运行您的实时应用程序并进行一些断言,同时直接控制浏览器行为,这样您就不会有时间模仿jQuery的方法甚至使用它。
Nightwatch,nightmare.js或Selenium是执行端到端测试的常用工具。
可能适合您的另一个工具是Quixote,这是一个用于css断言的工具。
有时,在处理前端代码时,即使在对基本功能进行单元测试时,也必须模拟本机浏览器api:在这种情况下,writing tight functions是可行的方法。
答案 1 :(得分:2)
听起来你真正关心的是你的应用程序如何与浏览器集成,而不一定是你自己控制的逻辑。这似乎是一个集成测试,在这种情况下,您不希望存根浏览器功能。在这种情况下,其他人提到的一些测试框架如Selenium可能是一个很好的方法(我可能也会建议Puppeteer,它具有setViewport功能)。
如果您将依赖项外部化,也可以将其写为单元测试,如果内部逻辑值得单独测试,则将宽度和高度传递到代码中并验证代码回应得恰到好处,但听起来好像这里的逻辑主要围绕与浏览器/ jQuery / DOM集成。
关于最佳实践,记住和探索的一个重要格言是don't mock code that you don't own - 如果你这样做,你就是嘲笑你无法控制的行为,可能会从你身下改变,也可能允许你的实现会泄漏到你的测试中。