我是javascript单元测试的新手,但我相信至少对一般的单元测试有所了解。
我正在尝试学习“ javascript方式”,并开始为我的客户端代码编写单元测试。
为此,我安装了以下库:
mocha.js和chai.js
出乎意料的是,一切进展顺利。
我设法轻松地包括了这些内容,并开始编写我的单元测试。
我正在使用ASP Core btw。尽管我发现VS2016是我使用过的该IDE的漏洞最多的版本(但我仅是一名专业专家,已经有5年了,所以我可能是错的),但新的MVC 6更改却为您提供了一种管理静态资源的简便方法(或客户端依赖项),让您使用Bower软件包管理器。
所以,回到测试。我从一小部分通用通用的简单javascript函数开始。尽管写得有些差,但他们提供了很好的练习。
但是,一段时间后,我需要开始嘲笑。通过用C#编写单元测试,我开始意识到这种类型的库的有用性。
由于这些概念绝非特定于C#而是仅适用于单元测试,因此我希望找到一个可提供这种功能的库-sinon.js。
再说一遍,一切进展顺利。
直到我不得不嘲笑诺言。
再次证明,有一个库可以帮助我解决这个问题-sinon-as-promised.js
经过相当多的努力,包括通过npm安装它,使用browserify之类的工具将其解析为一个脚本,以便在浏览器中使用等等,我相信我设法使它运行了。
此时,我可以执行以下操作:
let returnsPromise = sinon.stub($, "ajax").resolves('success');
这将使我成为一个“可实现的”对象(具有then()方法并且应该表现为承诺的东西)。
这里有一个小问题,它没有.done()和.fail()方法,在我的编码中我不知道它们是首选方法,但是我猜测有一种简单的方法可以将它们扩展到对象中。
在那之后,当我读到chai.js提供了一种管理承诺承诺的有效方法时,我甚至开始印象深刻。
我们在这里,我的问题。
我所说的关于柴的事情是“最终”的支持。一个让我做魔术的词,它避免了在then()的成功和错误回调中都使用.done()的情况,只是为了确保我们不会对诺言产生错误的肯定。
因此,应该这样使用它:
it('testing eventually', function () {
let returnsPromise = sinon.stub($, "ajax").resolves('success');
return expect(returnsPromise()).should.eventually.equal('success');
});
如果成功完成了想要的结果,这应该失败。
现在,您可以想象当我无法如愿以偿地跑步时我的失望。
我找不到该库的“浏览器友好”版本,因此,再次使用npm安装它之后,将其浏览器化为“应该在浏览器脚本中工作”,然后添加了它去派对。
但是,无论我做什么,在上面的示例中,都会出现以下错误:
TypeError: Cannot read property 'equal' of undefined
at Context.<anonymous> (js/miscellaneous-tests.js:94:58)
我将其解释为“我们最终不知道”是什么意思。这使我相信我添加chai-as-promised.js的方式无效。
此后,我尝试了很多事情。有些愚蠢,有些愚蠢,但是无论我如何尝试,都无法让代码“最终”理解
这些事情包括:
读取脚本并获取chai-as-promise的依赖关系并将其添加到解决方案中(既是browserify-ed,又以它们来自npm的形式),在第二种情况下,再次对其依赖项进行了相同的操作-直到我相信包裹丢失。
我尝试以多种不同的方式添加,删除文件,实际上我在编写此文件时会画一个空白-但我能想到的每种可能的组合-我都尝试过。
我用谷歌搜索“最终是不确定的”,类似的东西很多次,我认为谷歌对我有点生气,但我找不到我想要的东西
在某个时候,我开始在地板上画一个五角星形的大圆圈,但花了我一段时间(如今在办公室里找不到像处女的血液和蜡烛这样的东西)第二天回到办公室,那位清洁女工已将其擦除。
由于我没有主意,我希望你们中的一些人尝试在浏览器中进行一些javascript单元测试。
因为它涉及很多资源,说明和内容,并且此帖子已经超出了应有的时间,所以我创建了一个github存储库,在其中我已经上传了到目前为止所做的一切。
这是它的链接:
js-unit-test-mocking
顺便说一句,如果您不喜欢ASP或与Microsoft相关的任何内容,则运行它所需的所有内容都应该位于wwwroot中。
谢谢您的陪伴。抱歉,很长的帖子。
最佳答案
您的代码有两个问题:
您同时使用expect
和should
接口(expect(...).should.eventually.equal...)
。您应同时使用一个或另一个,但不能同时使用两者。
您忘记使用chai.use
的导出值调用chai-as-promised
了。我从以下事实推断出这一点:如果我故意忽略了这一点,那么我会得到与您完全相同的错误,并且我不知道有任何其他方法可以获取该错误。
无论您想做什么,都必须转换chai-as-promised
使其在浏览器中工作。由于您提到使用过browserify
,因此我将在答案中使用它。您可以使用webpack
甚至编写自己的脚本进行转换。
遵循两种一般策略。
仅变换chai-as-promised
这里的策略是将所有内容分开,仅转换chai-as-promised
使其在浏览器中工作。这是一个说明性的测试文件:
const expect = chai.expect;
mocha.setup("bdd");
chai.should();
// Commenting out this line reproduces the exact error message
// reported in the question.
chai.use(chaiAsPromised);
// Incorrect use of should with expect.
it('testing eventually incorrectly', function () {
return expect(Promise.resolve("success")).should.eventually.equal('success');
});
// Correct use of expect alone.
it('testing eventually with expect', function () {
return expect(Promise.resolve("success")).eventually.equal('success');
});
// Correct use of should alone.
it('testing eventually with should', function () {
return Promise.resolve("success").should.eventually.equal('success');
});
chai-as-promised
用以下命令转换:browserify -o chai-as-promised-built.js -s chaiAsPromised node_modules/chai-as-promised/lib/chai-as-promised.js
这实际上需要
chai-as-promised.js
并将其包装到代码中,以便它在CommonJS方言中正常导出的内容成为浏览器中的全局导出,并且该全局导出名为chaiAsPromised
(这是-s
选项的作用)。输出在chai-as-promise-built.js
中,这是您需要在浏览器中加载的内容。然后,您可以使用以下
index.html
文件:<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8"/>
<link href="./node_modules/mocha/mocha.css" type="text/css" media="screen" rel="stylesheet" />
<script type="text/javascript" src="./node_modules/mocha/mocha.js"></script>
<script type="text/javascript" src="./node_modules/chai/chai.js"></script>
<script type="text/javascript" src="./chai-as-promised-built.js"></script>
<script type="text/javascript" src="./test.js"></script>
</head>
<body>
<div id="mocha"></div>
<script>
mocha.run();
</script>
</body>
</html>
将所有内容捆绑到一个文件中
这里的策略是使用browserify将所有内容编译到一个文件中。对于某些项目,这是一个可行的选择。对于希望使用
require
编写代码而不是依赖于全局变量的项目,它也可能更可取。这是一个说明性的测试文件:const chai = require("chai");
const chaiAsPromised = require("chai-as-promised");
const expect = chai.expect;
const mocha = require("mocha");
mocha.mocha.setup("bdd");
chai.should();
// Commenting out this line reproduces the exact error message
// reported in the question.
chai.use(chaiAsPromised);
// Incorrect use of should with expect.
it('testing eventually incorrectly', function () {
return expect(Promise.resolve("success")).should.eventually.equal('success');
});
// Correct use of expect alone.
it('testing eventually with expect', function () {
return expect(Promise.resolve("success")).eventually.equal('success');
});
// Correct use of should alone.
it('testing eventually with should', function () {
return Promise.resolve("success").should.eventually.equal('success');
});
安装所需的模块后,请使用以下命令进行构建:
browserify -o built.js test.js
然后,您可以使用以下
index.html
文件加载它:<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8"/>
<link href="./node_modules/mocha/mocha.css" type="text/css" media="screen" rel="stylesheet" />
<script type="text/javascript" src="./built.js"></script>
</head>
<body>
<div id="mocha"></div>
<script>
mocha.run();
</script>
</body>
您会看到第一个测试将失败,因为它尝试同时使用
expect
和should
。随后的两个测试将通过。如果您注释掉
chai.use(chaiAsPromised);
所在的行,则会得到与问题报告完全相同的错误消息。如果确实更改了代码,请记住使用browserify
进行重建。关于javascript - 配置JavaScript单元测试并 promise 声明,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40655599/